﻿Imports System.Windows.Forms.DataVisualization
Imports AppDep = System.Deployment.Application
Imports System.Xml
Imports DevExpress
Imports SharpZip = ICSharpCode.SharpZipLib
Imports System.Threading.Tasks

Public Class frmEmployees

    Private logger As NLog.Logger = NLog.LogManager.GetCurrentClassLogger()


    ReadOnly EmpFile As String = IO.Path.Combine(My.Application.Info.DirectoryPath, My.Resources.EmployeeData)
    Private Const TagField As String = "Tag"
    Private employees As New EmployeeList
    Private Sub SetCaptionColor()
        Dim skin As Skins.Skin = Skins.CommonSkins.GetSkin(Me.LookAndFeel.ActiveLookAndFeel)

        Dim caption As Color = skin.TranslateColor(Drawing.SystemColors.WindowText)
        WorkHoursControl1.CaptionColor = caption
        lblCalendarGrouping.ForeColor = caption
        lblChartType.ForeColor = caption
        LabelblChartThemelControl5.ForeColor = caption
        lblEmployees.ForeColor = caption
        lblSemesterEnd.ForeColor = caption
        lblSemesterStart.ForeColor = caption
        lblUITheme.ForeColor = caption
        lblChartDate.ForeColor = caption


    End Sub
    Private Sub SetupLabels()


        'SchedulerStorage1.Appointments.Labels.Clear()
        'For x As Integer = SchedulerStorage1.Appointments.Labels.Count - 1 To 1 Step -1
        '    SchedulerStorage1.Appointments.Labels.RemoveAt(x)

        'Next
        SchedulerStorage1.Appointments.Labels.Clear()

        SchedulerStorage1.Appointments.Statuses.Clear()
        Dim tmpEmps As EmployeeList = GetEmps()
        With SchedulerStorage1.Appointments.Labels(SchedulerStorage1.Appointments.Labels.Add(Color.LightGray, ""))

        End With

        For Each emp As Employee In tmpEmps
            If emp.Color.HasValue Then
                Dim lbl As XtraScheduler.AppointmentLabel = SchedulerStorage1.Appointments.Labels(SchedulerStorage1.Appointments.Labels.Add(emp.Color, emp.Name))


            End If
        Next

        For Each st In tmpEmps.GetUniqueScheduleTypes
            'If Not tmpEmps.ScheduleColors.ContainsKey(st) Then
            '    tmpEmps.ScheduleColors.Add(st, Color.Empty)
            'End If
            With SchedulerStorage1.Appointments.Statuses(SchedulerStorage1.Appointments.Statuses.Add(tmpEmps.ScheduleColors(st).ToColor, st))
                .Type = XtraScheduler.AppointmentStatusType.Custom

            End With
        Next


    End Sub
    Private UpdatedChart As Boolean
    Private InUpdateChart As Boolean
    Private Sub SetupWorkHourExceptions(ByVal apt As XtraScheduler.Appointment)
        Dim oc As XtraScheduler.OccurrenceCalculator = XtraScheduler.OccurrenceCalculator.CreateInstance(apt.RecurrenceInfo)
        For Each exc As WorkHoursSettings.HourSettingException In employees.WorkHours.SettingsExceptions
            Dim tmpDt As Date = oc.FindNextOccurrenceTimeAfter(exc.ExceptionDate, apt)
            If tmpDt.Date = exc.ExceptionDate.Date Then

                Dim oci As Integer = oc.FindOccurrenceIndex(tmpDt, apt)
                Dim occ As DevExpress.XtraScheduler.Appointment = apt.GetOccurrence(oci)
                Dim st As Date = occ.Start
                Dim en As Date = occ.End
                Dim dofix As Boolean = False
                If occ.Start.TimeOfDay < exc.ExceptionStart.TimeOfDay Then
                    With exc
                        st = New Date(.ExceptionDate.Year, .ExceptionDate.Month, .ExceptionDate.Day, .ExceptionStart.Hour, .ExceptionStart.Minute, .ExceptionStart.Second)
                    End With
                    dofix = True
                End If
                If occ.End.TimeOfDay > exc.ExceptionEnd.TimeOfDay Then
                    With exc
                        en = New Date(.ExceptionDate.Year, .ExceptionDate.Month, .ExceptionDate.Day, .ExceptionEnd.Hour, .ExceptionEnd.Minute, .ExceptionEnd.Second)
                    End With
                    dofix = True
                End If
                If dofix Then
                    Dim occEx As DevExpress.XtraScheduler.Appointment = apt.CreateException(XtraScheduler.AppointmentType.ChangedOccurrence, oci)
                    occEx.Start = st
                    occEx.End = en
                    Dim pttmp As PointTag

                    pttmp = apt.CustomFields(TagField)


                    pttmp.WorkSettingException = exc
                    occ.CustomFields(TagField) = pttmp


                End If
            End If

        Next
    End Sub
    Private Function GetEmps() As EmployeeList
        Dim emps As New EmployeeList
        emps.ScheduleColors = employees.ScheduleColors
        emps.WorkHours = employees.WorkHours

        If beFilterEmployeeType.EditValue <> "" Then
            Dim types = From t In CType(beFilterEmployeeType.EditValue, String).Split(reFilterEmployeeTypes.SeparatorChar) Select t.Trim
            emps.AddRange(From e In employees Where types.Contains(e.EmployeeType))
        Else
            emps = employees
        End If

        If beFilterScheduleTypes.EditValue <> "" Then
            Dim types = From t In CType(beFilterScheduleTypes.EditValue, String).Split(reFilterScheduleTypes.SeparatorChar) Select t.Trim

            If types.Count <> reFilterScheduleTypes.Items.Count Then
                Dim filtered = From e In emps Where e.getUniqueScheduleTypes().Intersect(types).Count = 0 Select e Distinct



                emps.RemoveAll(Function(fe)
                                   Return filtered.Contains(fe)
                               End Function)

            End If
        End If

        If beFilterLocations.EditValue <> "" Then
            Dim locations = From l In CType(beFilterLocations.EditValue, String).Split(reFilterLocations.SeparatorChar) Select l.Trim

            If locations.Count <> reFilterLocations.Items.Count Then
                Dim filtered = From e In emps Where e.getUniqueLocations.Intersect(locations).Count = 0 Select e Distinct

                emps.RemoveAll(Function(fe)
                                   Return filtered.Contains(fe)
                               End Function)
            End If
        End If
        Return emps
    End Function

    Public Class EmpScheduleType
        Implements IEqualityComparer(Of EmpScheduleType)

        Property Employee As Employee
        Property ScheduleType As String

        Public Function Equals1(x As EmpScheduleType, y As EmpScheduleType) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of EmpScheduleType).Equals
            Return x.Employee.ID = y.Employee.ID AndAlso x.ScheduleType = y.ScheduleType


        End Function

        Public Function GetHashCode1(obj As EmpScheduleType) As Integer Implements System.Collections.Generic.IEqualityComparer(Of EmpScheduleType).GetHashCode
            Return obj.Employee.ID.GetHashCode Xor obj.ScheduleType.GetHashCode
        End Function
    End Class
    Private Sub UpdateChart()

        InUpdateChart = True
        chrtHours.Series.Clear()
        chrtHours.Annotations.Clear()

        chrtHours.ChartAreas(0).AxisY.IsInterlaced = True
        chrtHourNumbers.Series.Clear()
        chrtHours.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), My.Settings.Theme)
        chrtHourNumbers.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), My.Settings.Theme)

        employees.Sort()
        SchedulerControl1.BeginUpdate()
        'Dim holidays As XtraScheduler.WorkDay() = (From c In SchedulerControl1.WorkDays Where TypeOf c Is XtraScheduler.Holiday).ToArray
        'For Each hol As XtraScheduler.WorkDay In holidays
        '    SchedulerControl1.WorkDays.Remove(hol)
        'Next
        SchedulerStorage1.BeginUpdate()
        SchedulerStorage1.Appointments.Clear()
        ApplyWorkHours(employees.WorkHours)
        SchedulerStorage1.Resources.Clear()

        'Dim clSL As New Charting.StripLine
        'With clSL
        '    .Interval = 2
        '    .BackColor = Color.Black
        '    .BackSecondaryColor = Color.Red
        '    .BackGradientStyle = Charting.GradientStyle.Center


        'End With
        'chrtHours.ChartAreas(0).AxisY.StripLines.Add(clSL)
        SetupLabels()

        Dim lblIndex As Integer = 1
        Dim loadedGeneralHolidays As Boolean
        Dim types As String()
        If beFilterScheduleTypes.EditValue <> "" Then
            types = (From t In CType(beFilterScheduleTypes.EditValue, String).Split(reFilterScheduleTypes.SeparatorChar) Select t.Trim).ToArray
        Else
            types = {}
        End If

        Dim chrtFnt As New Font("Times New Roman", 12)
        Dim emps As EmployeeList = GetEmps()
        For Each emp As Employee In emps
            Dim res As New XtraScheduler.Resource(emp, emp.Name)
            Dim totHours As Double
            If dtChartView.EditValue Is Nothing AndAlso Now.Date < Me.employees.WorkHours.SemesterStart Then
                totHours = emp.TotalHours(employees.WorkHours, employees.WorkHours.SemesterStart, employees.Holidays, types.ToList)
            Else
                totHours = emp.TotalHours(employees.WorkHours, dtChartView.EditValue, employees.Holidays, types.ToList)
            End If
            SchedulerStorage1.Resources.Add(res)

            With chrtHourNumbers.Series.Add(emp.ID.ToString("B"))
                .AxisLabel = emp.Name
                .LegendText = emp.Name
                .ChartType = Charting.SeriesChartType.Bar
                Dim cur As Integer
                .Font = chrtFnt
                cur = .Points.AddXY(emps.IndexOf(emp) * -1, totHours)
                If emp.Name = "Closed" Then
                    .BackSecondaryColor = Color.White
                    ' .Item("DrawSideBySide") = True
                    .Color = Color.Black

                End If
                .Item("DrawSideBySide") = False
                .Points(cur).AxisLabel = emp.Name
                .Points(cur).Label = totHours.ToString("G")
                .Points(cur).LabelAngle = 90
                .BackGradientStyle = Charting.GradientStyle.HorizontalCenter
                '.Sort(Charting.PointSortOrder.Ascending, "AxisLabel")
                .Tag = emp

            End With

            With chrtHours.Series.Add(emp.ID.ToString("B"))
                .AxisLabel = emp.Name
                .LegendText = emp.Name
                .Font = chrtFnt
                '.BackGradientStyle = DataVisualization.Charting.GradientStyle.DiagonalLeft
                If emp.Name = "Closed" Then
                    .BackSecondaryColor = Color.White
                    ' .Item("DrawSideBySide") = True
                    .Color = Color.Black


                End If
                '.BackSecondaryColor = Color.Red
                .LegendToolTip = totHours.ToString & " hours"
                .Tag = emp
                .BackGradientStyle = Charting.GradientStyle.VerticalCenter
                .Item("DrawingStyle") = "Emboss"
                '.Item("DrawSideBySide") = False
                .YValueType = DataVisualization.Charting.ChartValueType.Time
                .XValueType = DataVisualization.Charting.ChartValueType.String
                If optgChartType.SelectedIndex = 1 Then
                    .ChartType = DataVisualization.Charting.SeriesChartType.RangeBar
                    chrtHours.ChartAreas(0).AxisY.IsReversed = False
                    chrtHours.ChartAreas(0).AxisX.IsReversed = True
                Else
                    .ChartType = DataVisualization.Charting.SeriesChartType.RangeColumn
                    chrtHours.ChartAreas(0).AxisY.IsReversed = True
                    chrtHours.ChartAreas(0).AxisX.IsReversed = False
                End If
                .YValuesPerPoint = 2
                '.IsXValueIndexed = True
                '.Item("DrawingStyle") = "Gantt"

                For x As Integer = 0 To emp.Days.Length - 1
                    Dim apts As New List(Of XtraScheduler.Appointment)
                    Dim dy As Day = emp.Days(x)
                    For d As Integer = 0 To dy.StartTimes.Length - 1

                        If (types Is Nothing OrElse types.Count = 0) OrElse (types.Contains(dy.ScheduleEmployeeTypes(d))) Then
                            Dim current As Integer = .Points.AddXY(x, dy.StartTimes(d), dy.EndTimes(d))
                            Dim p As Charting.DataPoint = .Points(current)
                            'p.Label = dy.StartTimes(d).ToShortTimeString & "-" & dy.EndTimes(d).ToShortTimeString
                            p.Label = "[" & emp.Name & "]"


                            If optgChartType.SelectedIndex = 0 OrElse optgChartType.SelectedIndex = -1 Then
                                p.LabelAngle = 90

                            Else
                                p.LabelAngle = 0
                            End If
                            'p.LabelForeColor = Color.Red
                            'p.LegendToolTip = emp.TotalHours
                            Dim ts As TimeSpan = GetDayTimeSpanFromDateRange(dy.StartTimes(d), dy.EndTimes(d))


                            p.LabelToolTip = emp.Name & " " & ts.TotalHours.ToString & " hours" & vbCrLf & dy.StartTimes(d).ToShortTimeString & "-" & dy.EndTimes(d).ToShortTimeString
                            If ts.TotalHours = 1 Then p.LabelToolTip = p.LabelToolTip.Replace("hours", "hour")
                            Dim pt As New PointTag(x, d)
                            p.Tag = pt
                            pt.Employee = emp
                            'Dim st As Date = GetNextDay(x, dy.StartTimes(d))
                            Dim strtDate As Date = GetNextDay(x, dy.StartTimes(d))
                            ' strtDate = strtDate.AddDays(x)
                            ' If strtDate.Date < dtRangeStart.DateTime.Date Then strtDate = strtDate.AddDays(7)

                            If emp.HireDate.HasValue Then
                                If emp.HireDate.Value > strtDate Then
                                    strtDate = GetNextDay(x, emp.HireDate)

                                End If
                            End If

                            Dim endDate As New Date(strtDate.Year, strtDate.Month, strtDate.Day, dy.EndTimes(d).Hour, dy.EndTimes(d).Minute, dy.EndTimes(d).Second)
                            Dim workend As DateTime = dy.EndTimes(d)
                            Dim workStart As DateTime = dy.StartTimes(d)
                            Dim apt As XtraScheduler.Appointment = SchedulerStorage1.CreateAppointment(XtraScheduler.AppointmentType.Pattern)


                            With apt
                                .ResourceId = emp
                                .Subject = emp.Name
                                .Start = strtDate
                                .End = endDate
                                .Location = dy.Locations(d)
                                Dim itmindex = d
                                .StatusId = SchedulerStorage1.Appointments.Statuses.IndexOf((From st In SchedulerStorage1.Appointments.Statuses Where st.DisplayName = dy.ScheduleEmployeeTypes(itmindex)).FirstOrDefault)
                                With .RecurrenceInfo
                                    .Range = XtraScheduler.RecurrenceRange.EndByDate
                                    .Type = XtraScheduler.RecurrenceType.Daily
                                    .Start = strtDate
                                    .End = New Date(workend.Year, workend.Month, workend.Day, workend.Hour, workend.Minute, workend.Second)

                                    If emp.FireDate.HasValue Then
                                        If .End > emp.FireDate.Value Then
                                            .End = New Date(emp.FireDate.Value.Year, emp.FireDate.Value.Month, emp.FireDate.Value.Day, endDate.Hour, endDate.Minute, endDate.Second) '.AddDays(-7)
                                        End If
                                    End If
                                    '.Duration = ts
                                    '.Duration = endDate.Subtract(strtDate)
                                    .Periodicity = 7
                                End With

                                '.End = dy.EndTimes(d)
                                '.Start = dy.StartTimes(d)
                                .CustomFields(TagField) = pt

                            End With

                            If emp.Color.HasValue Then
                                apt.LabelId = lblIndex
                            End If
                            apts.Add(apt)
                            'SchedulerStorage1.Appointments.Add(apt)



                            p.ToolTip = p.LabelToolTip


                            With .SmartLabelStyle
                                .Enabled = True
                                .AllowOutsidePlotArea = Charting.LabelOutsidePlotAreaStyle.Partial
                                .CalloutLineAnchorCapStyle = Charting.LineAnchorCapStyle.Diamond
                                .CalloutLineColor = Color.Red
                                .CalloutLineWidth = 2
                                .CalloutStyle = Charting.LabelCalloutStyle.Box
                                .MovingDirection = Charting.LabelAlignmentStyles.Bottom
                                .IsMarkerOverlappingAllowed = False
                                .MinMovingDistance = 10
                                .MaxMovingDistance = 100
                            End With

                            Dim tiWorkTime As New XtraScheduler.TimeInterval(workStart.Date, workend.Date.AddHours(23).AddMinutes(59))

                            Dim dt As Date? = dtChartView.EditValue
                            If Not dt.HasValue Then dt = Now.Date
                            If dt < employees.WorkHours.SemesterStart Then dt = employees.WorkHours.SemesterStart

                            Dim tiWeek As New DevExpress.XtraScheduler.TimeInterval(GetLastDay(DayOfWeek.Sunday, dt), GetNextDay(DayOfWeek.Saturday, dt).AddHours(23).AddMinutes(59))

                            If Not tiWorkTime.IntersectsWith(tiWeek) Then
                                .Points.Remove(p)
                            End If

                        End If
                    Next
                    For Each tr As TimeRangeException In From t As TimeRangeException In emp.Days(x).TimeExceptions Where t.ExceptionType = ExceptionTypes.Add

                        SetupTimeException(emp, tr, x, lblIndex)
                    Next
                    For Each apt As XtraScheduler.Appointment In apts
                        For Each tr As TimeRangeException In From t As TimeRangeException In emp.Days(x).TimeExceptions Where t.ExceptionType = ExceptionTypes.Replace Or t.ExceptionType = ExceptionTypes.Delete
                            SetupTimeException(apt, tr, lblIndex)
                        Next

                        For Each hi As HolidayInfo In emp.Holidays.Concat(employees.Holidays)
                            SetupHolidayapt(apt, hi)

                        Next

                        SetupWorkHourExceptions(apt)
                        loadedGeneralHolidays = True
                    Next
                    SchedulerStorage1.Appointments.AddRange(apts.ToArray)

                    For Each p As Charting.DataPoint In .Points

                        p.AxisLabel = emp.Days(p.XValue).Label
                    Next

                Next
            End With
            If emp.Color.HasValue Then
                lblIndex += 1
            End If

        Next

        Dim sl As New Charting.StripLine()
        With sl
            .Interval = 2
            .BackGradientStyle = Charting.GradientStyle.HorizontalCenter
            .BackColor = Color.RoyalBlue
            .BackSecondaryColor = Color.SkyBlue
            .IntervalType = Charting.DateTimeIntervalType.Auto
            .IntervalOffsetType = Charting.DateTimeIntervalType.Auto
            .IntervalOffset = 0.5
            .StripWidthType = Charting.DateTimeIntervalType.Auto
            .StripWidth = 1


        End With
        SchedulerStorage1.EndUpdate()
        chrtHours.ChartAreas(0).AxisX.StripLines.Clear()
        chrtHours.ChartAreas(0).AxisX.StripLines.Add(sl)
        'CreateHolidayAppts()
        SchedulerControl1.Invalidate()
        SchedulerControl1.EndUpdate()
        ShowNoCoverage()


        chrtHours.Invalidate()



        UpdatedChart = True
        InUpdateChart = False
    End Sub

    'Private Sub CreateHolidayAppts()
    '    Dim apts As DevExpress.XtraScheduler.AppointmentBaseCollection = DevExpress.XtraScheduler.Native.HolidaysHelper.GenerateHolidayAppointments(Me.SchedulerStorage1, Me.SchedulerControl1.WorkDays)
    '    For Each apt As XtraScheduler.Appointment In apts
    '        Dim pt As New PointTag(-1, -1)

    '        pt.IsHoliday = True


    '        apt.CustomFields(TagField) = pt

    '    Next
    '    SchedulerStorage1.BeginUpdate()
    '    Try
    '        SchedulerStorage1.Appointments.Items.AddRange(apts)

    '    Catch ex As Exception
    '    Finally
    '        SchedulerStorage1.EndUpdate()
    '    End Try
    'End Sub

    Private Sub SetupHolidayapt(ByVal apt As XtraScheduler.Appointment, ByVal hi As HolidayInfo)
        Dim oc As XtraScheduler.OccurrenceCalculator = XtraScheduler.OccurrenceCalculator.CreateInstance(apt.RecurrenceInfo)
        Dim dt As Date = oc.FindNextOccurrenceTimeAfter(hi.Day, apt)
        Dim exc As DevExpress.XtraScheduler.Appointment
       
        If dt.Date = hi.Day.Date Then
            exc = apt.CreateException(XtraScheduler.AppointmentType.DeletedOccurrence, oc.FindFirstOccurrenceIndex(New XtraScheduler.TimeInterval(hi.Day, New Date(hi.Day.Year, hi.Day.Month, hi.Day.Day, 23, 59, 59)), apt))
        Else
            If hi.EndDate.HasValue Then
                If dt.Date <= hi.EndDate.Value.Date Then
                    exc = apt.CreateException(XtraScheduler.AppointmentType.DeletedOccurrence, oc.FindFirstOccurrenceIndex(New XtraScheduler.TimeInterval(dt, New Date(dt.Year, dt.Month, dt.Day, 23, 59, 59)), apt))
                End If
            End If
        End If
        If hi.EndDate.HasValue Then
            Do While dt.Date <= hi.EndDate.Value.Date
                dt = oc.FindNextOccurrenceTimeAfter(dt, apt)
                If dt <= hi.EndDate.Value.Date Then
                    exc = apt.CreateException(XtraScheduler.AppointmentType.DeletedOccurrence, oc.FindFirstOccurrenceIndex(New XtraScheduler.TimeInterval(dt, New Date(dt.Year, dt.Month, dt.Day, 23, 59, 59)), apt))

                End If

            Loop
        End If

    End Sub

    Private Sub SetupTimeException(ByVal apt As XtraScheduler.Appointment, ByVal TR As TimeRangeException, Optional ByVal lblIndex As Integer = -1)
        If TR.ExceptionType = ExceptionTypes.Replace Then
            Dim oc As XtraScheduler.OccurrenceCalculator = XtraScheduler.OccurrenceCalculator.CreateInstance(apt.RecurrenceInfo)
            Dim dt As Date = oc.FindNextOccurrenceTimeAfter(TR.Day, apt)



            If dt.Date = TR.Day Then
                Dim pt As PointTag = apt.CustomFields(TagField)
                If pt.TimeRange = TR.TimeRange Then
                    Dim exc As XtraScheduler.Appointment = apt.CreateException(XtraScheduler.AppointmentType.ChangedOccurrence, oc.FindFirstOccurrenceIndex(New XtraScheduler.TimeInterval(TR.Day, New Date(TR.Day.Year, TR.Day.Month, TR.Day.Day, 23, 59, 59)), apt))
                    exc.Start = TR.StartTime
                    exc.End = TR.EndTime
                    exc.Location = TR.Location
                    exc.StatusId = SchedulerStorage1.Appointments.Statuses.IndexOf((From st In SchedulerStorage1.Appointments.Statuses Where st.DisplayName = TR.ScheduleType).FirstOrDefault)
                    pt.TimeRangeException = TR

                    exc.CustomFields(TagField) = pt
                    If lblIndex <> -1 Then exc.LabelId = lblIndex
                End If
            End If
        ElseIf TR.ExceptionType = ExceptionTypes.Delete Then
            Dim oc As XtraScheduler.OccurrenceCalculator = XtraScheduler.OccurrenceCalculator.CreateInstance(apt.RecurrenceInfo)
            Dim dt As Date = oc.FindNextOccurrenceTimeAfter(TR.Day, apt)
            If dt.Date = TR.Day Then
                Dim pt As PointTag = apt.CustomFields(TagField)
                If pt.TimeRange = TR.TimeRange Then
                    Dim exc As XtraScheduler.Appointment = apt.CreateException(XtraScheduler.AppointmentType.DeletedOccurrence, oc.FindFirstOccurrenceIndex(New XtraScheduler.TimeInterval(TR.Day, New Date(TR.Day.Year, TR.Day.Month, TR.Day.Day, 23, 59, 59)), apt))
                    exc.Start = TR.StartTime
                    exc.End = TR.EndTime
                    exc.Location = TR.Location
                    pt.TimeRangeException = TR
                    exc.CustomFields(TagField) = pt

                End If
            End If

        End If
    End Sub
    Private Sub SetupTimeException(ByVal emp As Employee, ByVal TR As TimeRangeException, ByVal Day As Integer, Optional ByVal lblIndex As Integer = 0)
        If TR.ExceptionType = ExceptionTypes.Add Then
            Dim apt As XtraScheduler.Appointment = SchedulerStorage1.CreateAppointment(XtraScheduler.AppointmentType.Normal)

            With apt
                .ResourceId = emp
                .StatusId = SchedulerStorage1.Appointments.Statuses.IndexOf((From st In SchedulerStorage1.Appointments.Statuses Where st.DisplayName = TR.ScheduleType).FirstOrDefault)
                .Subject = emp.Name
                .Start = TR.StartTime
                .End = TR.EndTime
                If emp.Color.HasValue Then .LabelId = lblIndex
                Dim pt As New PointTag(Day, -1)
                pt.TimeRangeException = TR
                pt.Employee = emp
                pt.Day = Day
                apt.CustomFields(TagField) = pt


            End With
            SchedulerStorage1.Appointments.Add(apt)
        End If
    End Sub
    Private Sub SetupShading()
        Dim cv As New XtraScheduler.Printing.PrintColorConverter
        cv.ApplyToAppointment = False
        'Dim s As XtraScheduler.Printing.DailyPrintStyle
        For Each ps As XtraScheduler.Printing.SchedulerPrintStyle In SchedulerControl1.PrintStyles

            ps.ColorConverter = cv.Clone
        Next




    End Sub
    Private Sub SetupChart(Optional ByVal ForWord As Boolean = False)
        chrtHours.Series.Clear()
        SchedulerStorage1.Appointments.CustomFieldMappings.Clear()
        SchedulerStorage1.Appointments.CustomFieldMappings.Add(New XtraScheduler.AppointmentCustomFieldMapping(TagField, TagField))
        Dim fnt As Font = chrtHours.ChartAreas(0).AxisY.LabelStyle.Font
        If ForWord Then
            fnt = New Font(fnt.Name, 14)
        End If

        With chrtHours.ChartAreas(0).AxisY
            .IntervalOffsetType = DataVisualization.Charting.DateTimeIntervalType.Minutes
            .IntervalType = DataVisualization.Charting.DateTimeIntervalType.Minutes
            .IntervalOffset = 30
            .Interval = 30
            '.IntervalAutoMode = DataVisualization.Charting.IntervalAutoMode.FixedCount
            .LabelStyle.Font = fnt
            Dim hoursettings As WorkHoursSettings = employees.WorkHours
            .Minimum = Date.Parse(String.Format("{0}:{1}", hoursettings.GetSmallestWorkingHour, hoursettings.GetSmallestWorkingMinute), Globalization.DateTimeFormatInfo.CurrentInfo, Globalization.DateTimeStyles.NoCurrentDateDefault).ToOADate
            .Maximum = Date.Parse(String.Format("{0}:{1}", hoursettings.GetLargestWorkingHour, hoursettings.GetLargestWorkingMinute), Globalization.DateTimeFormatInfo.CurrentInfo, Globalization.DateTimeStyles.NoCurrentDateDefault).ToOADate

            .IsReversed = True
            .IsInterlaced = True
            .InterlacedColor = Color.Cyan



        End With
        With chrtHours.ChartAreas(0).AxisX
            .MajorGrid.Enabled = False
            .MajorTickMark.Enabled = True
            .LabelAutoFitStyle = Charting.LabelAutoFitStyles.LabelsAngleStep30
            .IsMarginVisible = True



        End With
        With chrtHourNumbers.ChartAreas(0).AxisX
            .MajorGrid.Enabled = False
            .MajorTickMark.Enabled = True
            '.IsReversed = True




        End With
        chrtHours.Titles.Clear()
        chrtHourNumbers.Titles.Clear()
        With chrtHours.Titles.Add("Hours Overview")
            .Alignment = ContentAlignment.TopCenter
            .Docking = Charting.Docking.Top
        End With
        Dim dt As Date? = dtChartView.EditValue
        If Not dt.HasValue Then
            dt = Now.Date
            If dt < employees.WorkHours.SemesterStart Then dt = employees.WorkHours.SemesterStart
            If dt > employees.WorkHours.SemesterEnd Then dt = employees.WorkHours.SemesterEnd


        End If


        With chrtHours.Titles.Add(String.Format("{0} - {1}", GetLastDay(DayOfWeek.Sunday, dt.Value).ToLongDateString, GetNextDay(DayOfWeek.Saturday, dt.Value).ToLongDateString))
            .Alignment = ContentAlignment.TopCenter
            .Docking = Charting.Docking.Top
        End With
        With chrtHours.Titles.Add("*Does not count for time range exceptions and holidays.")
            .Alignment = ContentAlignment.TopLeft
            .Docking = Charting.Docking.Bottom
            .Font = New Font("Times New Roman", 7, FontStyle.Italic)

        End With



        With chrtHourNumbers.Titles.Add("Total Hours by Employee")
            .Alignment = ContentAlignment.TopCenter
            .Docking = Charting.Docking.Top
        End With
        With chrtHourNumbers.Titles.Add(String.Format("{0} - {1}", GetLastDay(DayOfWeek.Sunday, dt.Value).ToLongDateString, GetNextDay(DayOfWeek.Saturday, dt.Value).ToLongDateString))
            .Alignment = ContentAlignment.TopCenter
            .Docking = Charting.Docking.Top
        End With
        chrtHours.Legends(0).Docking = Charting.Docking.Bottom
        chrtHours.Palette = Charting.ChartColorPalette.SeaGreen
        chrtHourNumbers.Palette = Charting.ChartColorPalette.SeaGreen

    End Sub

    Dim tmps As New List(Of String)
    Private Function GetFilters() As SerializableDictionary(Of String, String)
        Dim filters As New SerializableDictionary(Of String, String)
        filters.Add("Employee Types", beFilterEmployeeType.EditValue)
        filters.Add("Schedule Types", beFilterScheduleTypes.EditValue)
        filters.Add("Locations", beFilterLocations.EditValue)
        Return filters

    End Function
    Private Sub updateScaleSetting()

        My.Settings.DayScale = SchedulerControl1.DayView.TimeScale
        My.Settings.WorkWeekScale = SchedulerControl1.WorkWeekView.TimeScale

    End Sub
    Private Sub frmEmployees_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        employees.Filters = GetFilters()
        updateScaleSetting()
        Dim msg As DialogResult = XtraEditors.XtraMessageBox.Show("Do you want to save the changes to the working file?  The program will load the file on the next run.", "Save Data?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
        Select Case msg
            Case Windows.Forms.DialogResult.Yes
                If AppDep.ApplicationDeployment.IsNetworkDeployed Then
                    employees.Save(AppDep.ApplicationDeployment.CurrentDeployment.DataDirectory & "\" & IO.Path.GetFileName(EmpFile))
                Else
                    employees.Save(EmpFile)
                End If
                For Each tmp In tmps
                    Try
                        IO.File.Delete(tmp)
                    Catch ex As Exception

                    End Try
                Next

            Case Windows.Forms.DialogResult.Cancel
                e.Cancel = True
        End Select
    End Sub
    Private Sub LoadFilters(Optional SelectAll As Boolean = False)
        LoadEmployeeTypes(SelectAll)
        LoadScheduleTypes(SelectAll)
        LoadLocations(SelectAll)
    End Sub

    Sub reloadFilters()
        LoadFilters(True)
        For Each f In employees.Filters
            Select Case f.Key
                Case "Employee Types"
                    If Not (String.IsNullOrEmpty(f.Value)) AndAlso f.Value <> "(Any)" Then
                        beFilterEmployeeType.EditValue = f.Value
                    End If
                Case "Schedule Types"
                    If Not (String.IsNullOrEmpty(f.Value)) AndAlso f.Value <> "(Any)" Then
                        beFilterScheduleTypes.EditValue = f.Value
                    End If
                Case "Locations"
                    If Not (String.IsNullOrEmpty(f.Value)) AndAlso f.Value <> "(Any)" Then
                        beFilterLocations.EditValue = f.Value
                    End If
            End Select
        Next

    End Sub

    Private Sub LoadFilterControl(SelectAll As Boolean, ByVal ctrl As XtraBars.BarEditItem, rep As DevExpress.XtraEditors.Repository.RepositoryItemCheckedComboBoxEdit, items As List(Of String))

        Dim oldItems = (From ci As DevExpress.XtraEditors.Controls.CheckedListBoxItem In rep.GetItems() Select ci.Value).Cast(Of String)().ToList
        Dim selected As String = ""
        Dim selecteditems As String()
        If rep.Items.Count > 0 Then
            selected = ctrl.EditValue.replace(rep.SeparatorChar & " ", rep.SeparatorChar)

            If selected IsNot Nothing Then selecteditems = selected.Split(rep.SeparatorChar)

        End If



        With rep
            .Items.Clear()
            .BeginUpdate()
            For Each et In items
                .Items.Add(et, True)

            Next
            .EndUpdate()
            ctrl.Refresh()

            If Not HaveSetupChart OrElse SelectAll = True Then
                ctrl.EditValue = String.Join(rep.SeparatorChar, items).Replace(rep.SeparatorChar & " ", rep.SeparatorChar)
            Else
                If selecteditems IsNot Nothing Then
                    Dim exclude = selecteditems.Except(items)
                    Dim add = items.Except(oldItems.ToList)

                    ctrl.EditValue = String.Join(rep.SeparatorChar, selecteditems.Except(exclude).Union(add)).Replace(rep.SeparatorChar & " ", rep.SeparatorChar)
                Else
                    ctrl.EditValue = String.Join(rep.SeparatorChar, items).Replace(rep.SeparatorChar & " ", rep.SeparatorChar)
                End If
            End If


        End With
        ctrl.Refresh()
    End Sub

    Private Sub LoadLocations(Optional SelectAll As Boolean = False)
        LoadFilterControl(SelectAll, beFilterLocations, reFilterLocations, employees.GetUniqueLocations)

    End Sub

    Private Sub LoadEmployeeTypes(Optional SelectAll As Boolean = False)
        LoadFilterControl(SelectAll, beFilterEmployeeType, reFilterEmployeeTypes, employees.GetUniqueEmployeeTypes)
    End Sub

    Private Sub LoadScheduleTypes(Optional SelectAll As Boolean = False)

        Dim Types As List(Of String) = employees.GetUniqueScheduleTypes
        ScheduleColors.ScheduleColors = employees.ScheduleColors
        ScheduleColors.ScheduleTypes = Types
        LoadFilterControl(SelectAll, beFilterScheduleTypes, reFilterScheduleTypes, Types)
    End Sub

    Private Sub frmEmployees_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ofdEmployee.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

        Dim skm As Skins.SkinManager = Skins.SkinManager.Default
        ' cboLayoutTheme.Properties.Items.AddRange(ski.Skins(0).GetSkins(0))
        For Each skc As Skins.SkinContainer In skm.Skins
            'cboLayoutTheme.Properties.Items.AddRange(skc.GetSkin
            For Each skn As Skins.Skin In skc.GetSkins
                If Not cboLayoutTheme.Properties.Items.Contains(skn.Name) Then cboLayoutTheme.Properties.Items.Add(skn.Name)
            Next
        Next
        cboLayoutTheme.SelectedItem = My.Settings.FormTheme
        ChangeSkin = True
        If Not AppDep.ApplicationDeployment.IsNetworkDeployed Then
            employees = EmployeeList.LoadEmployees(EmpFile)

        Else
            employees = EmployeeList.LoadEmployees(AppDep.ApplicationDeployment.CurrentDeployment.DataDirectory & "\" & IO.Path.GetFileName(EmpFile))

        End If
        reloadFilters()



        Dim vtype As DevExpress.XtraScheduler.SchedulerViewType = XtraScheduler.SchedulerViewType.WorkWeek
        If [Enum].TryParse(My.Settings.CalendarView, vtype) Then
            SchedulerControl1.ActiveViewType = vtype
        End If
        SchedulerControl1.DayView.TimeScale = My.Settings.DayScale
        SchedulerControl1.WorkWeekView.TimeScale = My.Settings.WorkWeekScale

        If My.Settings.CheckNoCoverage Then
            dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.AutoHide
        Else
            dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.Hidden
        End If
        WorkHoursControl1.HourSettings = employees.WorkHours
        dtRangeStart.DateTime = employees.WorkHours.SemesterStart
        dtRangeEnd.DateTime = employees.WorkHours.SemesterEnd
        SetupChart()
        SetupShading()
        employees.Sort()
        For Each emp As Employee In employees
            emp.Holidays.Sort()

        Next
        lbEmployees.Items.AddRange(employees.ToArray)
        If employees.Count > 0 Then lbEmployees.SelectedIndex = 0
        ' UpdateEnabled()
        'UpdateChart()
        chrtHours.Printing.PrintDocument = New Drawing.Printing.PrintDocument
        chrtHours.Printing.PrintDocument.PrinterSettings.DefaultPageSettings.Margins = New Drawing.Printing.Margins(50, 50, 50, 50)
        AddHandler chrtHours.Printing.PrintDocument.PrintPage, AddressOf pd_PrintPage
        chrtHours.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), My.Settings.Theme)
        chrtHourNumbers.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), My.Settings.Theme)
        Dim PalCol As String() = [Enum].GetNames(GetType(Charting.ChartColorPalette))
        Array.Sort(PalCol)

        cboPal.Properties.Items.AddRange(PalCol)
        cboPal.SelectedItem = chrtHours.Palette.ToString



        Dim dt As Date = Now.Date
        dt = New Date(dt.Year, dt.Month, dt.Day, 7, 30, 0)
        dt = GetLastDay(DayOfWeek.Monday, Now.Date)

        SchedulerControl1.Start = dt


        cboGroup.SelectedIndex = My.Settings.CalendarGrouping
#If DEBUG Then
        barTestUpdate.Visibility = XtraBars.BarItemVisibility.Always
#End If
        dpMakePortable.Visibility = XtraBars.Docking.DockVisibility.Hidden
        If My.Settings.InstallType = InstallTypes.Portable.ToString Then
            bbtnMakePortable.Visibility = XtraBars.BarItemVisibility.Never
        End If
    End Sub
    Private Function GetTMPFile() As String
        If Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then
            Return IO.Path.Combine(Deployment.Application.ApplicationDeployment.CurrentDeployment.DataDirectory, "tmp.dat")
        Else
            tmps.Add(My.Computer.FileSystem.GetTempFileName)

            Return tmps(tmps.Count - 1)

        End If

    End Function
    Private Sub ShowHours(Optional Tag As PointTag = Nothing)
        If lbEmployees.SelectedIndex = -1 Then Return
        Dim skin As Skins.Skin = Skins.CommonSkins.GetSkin(Me.LookAndFeel.ActiveLookAndFeel)
        Dim hours As frmHours
        If Tag Is Nothing Then
            hours = New frmHours(lbEmployees.SelectedItem, employees, skin)
        Else
            hours = New frmHours(Tag.Employee, employees, skin, Tag.Day)
        End If


        Dim pth As String = GetTMPFile()
        employees.Filters = GetFilters()
        employees.Save(pth)
        inShowHours = True
        If hours.ShowDialog() = Windows.Forms.DialogResult.Cancel Then
            employees = EmployeeList.LoadEmployees(pth)
            Dim id As Guid = DirectCast(lbEmployees.SelectedItem, Employee).ID
            lbEmployees.Items.Clear()
            lbEmployees.Items.AddRange(employees.ToArray)


            Try
                lbEmployees.SelectedItem = (From emp In employees Where emp.ID = id).First()
            Catch ex As Exception

            End Try


            reloadFilters()

        Else
            LoadFilters()
        End If

        Debug.WriteLine(beFilterScheduleTypes.EditValue)

        beFilterEmployeeType.Refresh()
        beFilterScheduleTypes.Refresh()
        RefreshData()
        Debug.WriteLine(beFilterScheduleTypes.EditValue)
        inShowHours = False
    End Sub
    Private inShowHours As Boolean = False






    Private Sub lbEmployees_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbEmployees.DoubleClick
        ShowHours()
    End Sub
    Private Sub UpdateTimeCaptions(ByVal Caption As String)
        bbtnAddTimeException.Caption = Caption
        mnuAddTime.Caption = Caption
    End Sub
    Private Sub UpdateHolidayCaptions(ByVal Caption As String)
        bbtnAddHoliday.Caption = Caption
        mnuAddHoliday.Caption = Caption
    End Sub

    Private Sub lbEmployees_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbEmployees.SelectedIndexChanged
        UpdateEnabled()


        If lbEmployees.SelectedIndex <> -1 Then
            Dim emp As Employee = employees(lbEmployees.SelectedIndex)
            UpdateTimeCaptions("Add time for " & emp.Name)
            UpdateHolidayCaptions("Add holiday for " & emp.Name)


        Else
            UpdateTimeCaptions("")
            UpdateHolidayCaptions("")


        End If
    End Sub
    Private Function ShouldEnable() As Boolean

        If employees.Count = 0 Then Return False
        Dim ti As XtraScheduler.TimeInterval = SchedulerControl1.SelectedInterval
        If ti Is Nothing OrElse ti.LongerThanADay Then Return False
        Dim work As XtraScheduler.TimeInterval = employees.WorkHours.DayToWorkingTimeInterval(ti.Start.Date)
        If work.Start > ti.Start OrElse work.End < ti.End Then Return False
        Return True
    End Function
    Private Sub UpdateEnabled()
        bbtnRemoveEmployee.Enabled = (lbEmployees.SelectedIndex > -1)
        bbtnAddTimeException.Enabled = (lbEmployees.SelectedIndex > -1)
        bbtnModifyEmployee.Enabled = (lbEmployees.SelectedIndex > -1)
        bbtnPrintCalendar.Enabled = (employees.Count >= 1)
        bbtnPrintCharts.Enabled = (employees.Count >= 1)
        If ShouldEnable() Then
            bbtnAddTimeException.Visibility = XtraBars.BarItemVisibility.Always
            bbtnAddHoliday.Links(0).BeginGroup = False


        Else
            bbtnAddTimeException.Visibility = XtraBars.BarItemVisibility.Never
            bbtnAddHoliday.Links(0).BeginGroup = True
        End If

        If lbEmployees.SelectedIndex = -1 Then
            bbtnAddHoliday.Visibility = XtraBars.BarItemVisibility.Never
        Else
            bbtnAddHoliday.Visibility = XtraBars.BarItemVisibility.Always
        End If



    End Sub



    Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        RefreshData()

        Dim chrthSize As Size = New Size(chrtHours.Size)
        Dim pd As Drawing.Printing.PrintDocument = sender
        Dim chrtNumSize As Size = New Size(chrtHourNumbers.Size)
        If bchkGrayScale.EditValue Then
            pd.DefaultPageSettings.Color = False
            chrtHours.ChartAreas(0).AxisY.IsInterlaced = False
            Dim sl As New Charting.StripLine()
            With sl
                .Interval = 2
                .BackGradientStyle = Charting.GradientStyle.HorizontalCenter
                .BackColor = Color.DarkGray
                .BackSecondaryColor = Color.LightGray
                .IntervalType = Charting.DateTimeIntervalType.Auto
                .IntervalOffsetType = Charting.DateTimeIntervalType.Auto
                .IntervalOffset = 0.5
                .StripWidthType = Charting.DateTimeIntervalType.Auto
                .StripWidth = 1

            End With
            chrtHours.ChartAreas(0).AxisX.StripLines.Clear()
            chrtHours.ChartAreas(0).AxisX.StripLines.Add(sl)
        End If
        For Each ser As Charting.Series In chrtHours.Series
            If bchkGrayScale.EditValue Then
                ser.Palette = Charting.ChartColorPalette.Grayscale
            End If
            Dim emp As Employee = ser.Tag
            For Each pt As Charting.DataPoint In ser.Points
                Dim an As New Charting.CalloutAnnotation
                With an
                    an.Text = pt.XValue.ToString
                    an.AnchorDataPoint = pt
                    .CalloutStyle = Charting.CalloutStyle.Perspective
                    .TextStyle = Charting.TextStyle.Frame
                    .ForeColor = Color.Black
                    .Font = New Font("Arial", 10)
                    .Height = 35
                    .Width = 50
                    .ForeColor = Color.FromArgb(128, Color.LightGoldenrodYellow)
                    With .SmartLabelStyle
                        .Enabled = True
                        .AllowOutsidePlotArea = Charting.LabelOutsidePlotAreaStyle.Yes
                        .IsMarkerOverlappingAllowed = False

                    End With
                    .ResizeToContent()
                    an.BringToFront()
                End With
                pt.Label = "[" & emp.Name & "]"

                Dim tag As PointTag = pt.Tag
                If emp.Days(tag.Day).StartTimes(tag.TimeRange).Minute Mod 30 <> 0 OrElse emp.Days(tag.Day).EndTimes(tag.TimeRange).Minute Mod 30 <> 0 Then chrtHours.Annotations.Add(an)
            Next
        Next
        'For Each ser As Charting.Series In chrtHourNumbers.Series
        '    If chkBW.Checked Then
        '        ser.Palette = Charting.ChartColorPalette.Grayscale
        '        chrtHours.Palette = Charting.ChartColorPalette.Grayscale
        '    End If
        'Next
        If bchkGrayScale.EditValue Then
            chrtHours.Palette = Charting.ChartColorPalette.Grayscale
            chrtHourNumbers.Palette = Charting.ChartColorPalette.Grayscale
        End If
        If bchkIncludeHours.EditValue Then
            chrtHours.Size = New Size(e.MarginBounds.Size.Width, Math.Max(e.MarginBounds.Size.Height / 2, 468))
            chrtHourNumbers.Size = New Size(e.MarginBounds.Size.Width, e.MarginBounds.Size.Height / 2)


            Dim chartPosition As New Rectangle(e.MarginBounds.X, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height / 2)

            Dim chartWidthScale As Single = CSng(e.MarginBounds.Width) / CSng(chartPosition.Width)
            Dim chartHeightScale As Single = CSng(e.MarginBounds.Height) / CSng(chartPosition.Height)
            chartPosition.Width = CInt(chartPosition.Width * Math.Min(chartWidthScale, chartHeightScale))
            chartPosition.Height = CInt(chartPosition.Height * Math.Min(chartWidthScale, chartHeightScale))
            chrtHours.Printing.PrintPaint(e.Graphics, chartPosition)
            chartPosition.Y += chartPosition.Height + 1

            chartPosition = New Rectangle(e.MarginBounds.X, chartPosition.Y, e.MarginBounds.Width, e.MarginBounds.Height / 2 - 4)
            chartWidthScale = CSng(e.MarginBounds.Width) / CSng(chartPosition.Width)
            chartHeightScale = CSng(e.MarginBounds.Height) / CSng(chartPosition.Height)
            chartPosition.Width = CInt(chartPosition.Width * Math.Min(chartWidthScale, chartHeightScale))
            chartPosition.Height = CInt(chartPosition.Height * Math.Min(chartWidthScale, chartHeightScale))
            chrtHourNumbers.Printing.PrintPaint(e.Graphics, chartPosition)
        Else
            chrtHours.Size = New Size(e.MarginBounds.Size.Width, e.MarginBounds.Size.Height)
            chrtHourNumbers.Size = New Size(e.MarginBounds.Size.Width, e.MarginBounds.Size.Height)


            Dim chartPosition As New Rectangle(e.MarginBounds.X, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height)

            'Dim chartWidthScale As Single = CSng(e.MarginBounds.Width) / CSng(chartPosition.Width)
            'Dim chartHeightScale As Single = CSng(e.MarginBounds.Height) / CSng(chartPosition.Height)
            'chartPosition.Width = CInt(chartPosition.Width * Math.Min(chartWidthScale, chartHeightScale))
            'chartPosition.Height = CInt(chartPosition.Height * Math.Min(chartWidthScale, chartHeightScale))
            chrtHours.Printing.PrintPaint(e.Graphics, chartPosition)
        End If


        chrtHours.Size = chrthSize
        chrtHourNumbers.Size = chrtNumSize
        RefreshData()
        'UpdateChart()


    End Sub
    Dim HaveSetupChart As Boolean
    Private Sub cboPal_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboPal.SelectedIndexChanged
        If Not HaveSetupChart Or cboPal.SelectedIndex = -1 Then Return

        chrtHours.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), cboPal.SelectedItem)
        chrtHourNumbers.Palette = [Enum].Parse(GetType(Charting.ChartColorPalette), cboPal.SelectedItem)
        My.Settings.Theme = chrtHours.Palette.ToString
    End Sub

    Private Sub chrtHours_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chrtHours.Click
        XtraTabControl1.Focus()
    End Sub

    Private Sub chrtHours_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles chrtHours.DoubleClick
        Dim LocalMousePosition As Point = chrtHours.PointToClient(Cursor.Position)

        Dim ht As Charting.HitTestResult = chrtHours.HitTest(LocalMousePosition.X, LocalMousePosition.Y)
        If ht.ChartElementType = Charting.ChartElementType.DataPointLabel Or ht.ChartElementType = Charting.ChartElementType.DataPoint Then
            Dim pt As Charting.DataPoint = ht.Series.Points(ht.PointIndex)
            Dim emp As Employee = ht.Series.Tag
            Dim pTag As PointTag = pt.Tag
            Dim d As Integer = pTag.Day
            Dim skin As Skins.Skin = Skins.CommonSkins.GetSkin(Me.LookAndFeel.ActiveLookAndFeel)
            employees.Save(GetTMPFile)

            Using mh As New frmHours(emp, employees, skin, d)
                If mh.ShowDialog() = Windows.Forms.DialogResult.Cancel Then

                    employees = EmployeeList.LoadEmployees(tmps(tmps.Count - 1))


                End If
            End Using

        End If
        RefreshData()



    End Sub
    Private lblColor As Color = Color.Black
    'Private Sub btnColor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    'cdLabel.Color = lblColor
    'If cdLabel.ShowDialog = Windows.Forms.DialogResult.OK Then
    '    For Each ser As Charting.Series In chrtHours.Series
    '        ser.LabelForeColor = cdLabel.Color

    '    Next
    '    lblColor = cdLabel.Color
    'End If
    'End Sub

    Private Sub chrtHours_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles chrtHours.Resize
        Debug.WriteLine("chart Height:" & chrtHours.Size.Height)
    End Sub

    Private Sub SchedulerControl1_ActiveViewChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles SchedulerControl1.ActiveViewChanged
        If HaveSetupChart Then
            My.Settings.CalendarView = SchedulerControl1.ActiveViewType.ToString

        End If
    End Sub

    Private Sub SchedulerControl1_AllowAppointmentDelete(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.AppointmentOperationEventArgs) Handles SchedulerControl1.AllowAppointmentDelete
        If RestoringAppointment Then Return


        Try
            Dim pt As PointTag = e.Appointment.CustomFields(TagField)

            If pt.IsHoliday Then

                Dim hol As HolidayInfo = pt.Holiday
                If hol.IsGeneralHoliday Then

                    e.Allow = True

                Else
                    e.Allow = False
                End If


            ElseIf pt.TimeRangeException Is Nothing Then
                'normal appointment
                e.Allow = True

            Else

                Dim emp As Employee = e.Appointment.ResourceId

                Dim tr As TimeRangeException = pt.TimeRangeException
                If tr.ExceptionType = ExceptionTypes.Add Then
                    e.Allow = True
                    emp.Days(pt.Day).TimeExceptions.Remove(tr)
                Else
                    'handle replace now handled in storage AppointmentDeleting event as suggested by http://www.devexpress.com/Support/Center/Question/Details/Q436266


                End If



            End If
        Catch ex As Exception
            logger.DebugException("Error delete allow.", ex)
        End Try

        ShowNoCoverage()
    End Sub



    Private Function AllowDrag(ByVal e As XtraScheduler.AppointmentDragEventArgs) As Boolean
        Dim tag As PointTag = e.SourceAppointment.CustomFields(TagField)
        If e.SourceAppointment.Type = XtraScheduler.AppointmentType.Normal Then
            If tag.TimeRangeException Is Nothing Then Return False
            If tag.TimeRangeException.ExceptionType = ExceptionTypes.Add Then Return True
            
        Else
            Return True
        End If

    End Function

    Private Sub SchedulerControl1_AppointmentDrag(ByVal sender As Object, ByVal e As XtraScheduler.AppointmentDragEventArgs) Handles SchedulerControl1.AppointmentDrag


        e.Allow = AllowDrag(e)


    End Sub
    Private RestoringAppointment As Boolean
    Private DeletedHoliday As Boolean = False
    Private Sub SchedulerControl1_AppointmentDrop(ByVal sender As Object, ByVal e As XtraScheduler.AppointmentDragEventArgs) Handles SchedulerControl1.AppointmentDrop
        Dim apt As XtraScheduler.Appointment = e.EditedAppointment

        Dim pt As PointTag = apt.CustomFields(TagField)
        Dim emp As Employee = Nothing
        If Not pt.IsHoliday Then emp = apt.ResourceId
        If e.SourceAppointment.Start.Date <> apt.Start.Date AndAlso Not pt.IsHoliday Then
            e.Allow = False
            e.Handled = True
            Return
        End If
        If Not pt.IsHoliday Then
            Dim work As DevExpress.XtraScheduler.TimeInterval = WorkHoursControl1.HourSettings.DayToWorkingTimeInterval(apt.Start)
            If apt.Start < work.Start OrElse apt.End > work.End Then
                e.Allow = False
                e.Handled = True
                Return
            End If
        End If
        Dim rmvApt As XtraScheduler.Appointment
        If apt.Type = XtraScheduler.AppointmentType.ChangedOccurrence Or apt.Type = XtraScheduler.AppointmentType.Occurrence Then

            Dim ans As DialogResult

            If apt.Type = XtraScheduler.AppointmentType.ChangedOccurrence Then
                ans = Windows.Forms.DialogResult.No

            Else
                ans = XtraEditors.XtraMessageBox.Show("Do you want to update this series?  If you do the selected day's worktime will be adjusted for every time.  If no this will create a worktime exception.  Cancel to undo.", "Update Weekly Time?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
            End If
            Select Case ans
                Case Windows.Forms.DialogResult.Yes
                    rmvApt = e.SourceAppointment.RecurrencePattern
                    Dim strtDate, endDate, recStart, recEnd, tmps, tmpe As Date
                    tmps = emp.Days(pt.Day).StartTimes(pt.TimeRange)
                    tmpe = emp.Days(pt.Day).EndTimes(pt.TimeRange)
                    Dim sch As String = emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange)
                    Dim loc As String = emp.Days(pt.Day).Locations(pt.TimeRange)

                    strtDate = New Date(tmps.Year, tmps.Month, tmps.Day, apt.Start.Hour, apt.Start.Minute, apt.Start.Second)
                    endDate = New Date(tmpe.Year, tmpe.Month, tmpe.Day, apt.End.Hour, apt.End.Minute, apt.End.Second)
                    recStart = e.SourceAppointment.RecurrenceInfo.Start
                    recEnd = e.SourceAppointment.RecurrenceInfo.End
                    emp.Days(pt.Day).RemoveTimeRange(pt.TimeRange)
                    rmvApt.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    rmvApt.End = New Date(recStart.Year, recStart.Month, recStart.Day, endDate.Hour, endDate.Minute, 0)
                    rmvApt.RecurrenceInfo.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    rmvApt.RecurrenceInfo.End = New Date(recEnd.Year, recEnd.Month, recEnd.Day, endDate.Hour, endDate.Minute, 0)

                    emp.Days(pt.Day).AddTimeRange(strtDate, endDate, sch, loc)

                    e.SourceAppointment.BeginUpdate()
                    e.SourceAppointment.Start = apt.Start
                    e.SourceAppointment.End = apt.End

                    e.SourceAppointment.RecurrenceInfo.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    e.SourceAppointment.RecurrenceInfo.End = New Date(recEnd.Year, recEnd.Month, recEnd.Day, endDate.Hour, endDate.Minute, 0)
                    'apt.RestoreOccurrence()
                    e.SourceAppointment.EndUpdate()
                    RestoringAppointment = True
                    e.SourceAppointment.RestoreOccurrence()
                    RestoringAppointment = False
                    SetupWorkHourExceptions(rmvApt)
                    ShowNoCoverage()

                    e.Handled = True
                    e.Allow = False


                Case Windows.Forms.DialogResult.No

                    Dim trs As List(Of TimeRangeException) = (From te In emp.Days(pt.Day).TimeExceptions Where te.Day.Date = apt.Start.Date And te.TimeRange = pt.TimeRange And te.StartTime = e.SourceAppointment.Start And te.EndTime = e.SourceAppointment.End).ToList

                    For Each tre As TimeRangeException In trs
                        emp.Days(pt.Day).TimeExceptions.Remove(tre)
                    Next
                    Dim tr As TimeRangeException = New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange, emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange), emp.Days(pt.Day).Locations(pt.TimeRange))
                    emp.Days(pt.Day).TimeExceptions.Add(tr)
                    pt.TimeRangeException = tr
                    'apt.RestoreOccurrence()
                    e.EditedAppointment.CustomFields(TagField) = pt
                    ShowNoCoverage()
                Case Windows.Forms.DialogResult.Cancel

                    e.Allow = False
                    e.Handled = True

            End Select
            Else
                If Not pt.IsHoliday Then


                    Dim trs As List(Of TimeRangeException) = (From te In emp.Days(pt.Day).TimeExceptions Where te.Day.Date = apt.Start.Date And te.TimeRange = pt.TimeRange And te.StartTime = e.SourceAppointment.Start And te.EndTime = e.SourceAppointment.End).ToList

                    For Each tre As TimeRangeException In trs
                        emp.Days(pt.Day).TimeExceptions.Remove(tre)
                    Next
                    Dim tr As TimeRangeException = New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange, emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange), emp.Days(pt.Day).Locations(pt.TimeRange), ExceptionTypes.Add)
                    emp.Days(pt.Day).TimeExceptions.Add(tr)
                    pt.TimeRangeException = tr
                    'apt.RestoreOccurrence()
                    e.EditedAppointment.CustomFields(TagField) = pt
                    ShowNoCoverage()
                Else
                    If e.EditedAppointment.AllDay Then



                        Dim hi As HolidayInfo = pt.Holiday
                        hi.Day = e.EditedAppointment.Start
                        If hi.EndDate.HasValue Then hi.EndDate = e.EditedAppointment.End.AddDays(-1)
                        e.EditedAppointment.CustomFields(TagField) = pt
                        employees.Holidays.Remove(hi)
                        employees.Holidays.Add(hi)
                        employees.Holidays.Sort()

                        tmrRebuild.Enabled = True
                    Else
                        e.Allow = False
                        e.Handled = True
                    End If
                End If

            End If
            e.EditedAppointment.LabelId = e.SourceAppointment.LabelId
            'RefreshData()
    End Sub

    Private Sub SchedulerControl1_AppointmentResized(ByVal sender As Object, ByVal e As XtraScheduler.AppointmentResizeEventArgs) Handles SchedulerControl1.AppointmentResized
        Dim apt As XtraScheduler.Appointment = e.EditedAppointment
        ' Stop
        Dim pt As PointTag = apt.CustomFields(TagField)
        Dim emp As Employee = Nothing
        If Not pt.IsHoliday Then emp = apt.ResourceId
        If e.SourceAppointment.Start.Date <> apt.Start.Date AndAlso Not pt.IsHoliday Then
            e.Allow = False
            e.Handled = True
            Return
        End If
        If Not pt.IsHoliday Then
            Dim work As DevExpress.XtraScheduler.TimeInterval = WorkHoursControl1.HourSettings.DayToWorkingTimeInterval(apt.Start)
            If apt.Start < work.Start OrElse apt.End > work.End Then
                e.Allow = False
                e.Handled = True
                Return

            End If
        End If
        Dim rmvApt As XtraScheduler.Appointment
        If apt.Type = XtraScheduler.AppointmentType.ChangedOccurrence Or apt.Type = XtraScheduler.AppointmentType.Occurrence Then




            Dim ans As DialogResult = XtraEditors.XtraMessageBox.Show("Do you want to update this series?  If you do the slected day's worktime will be adjusted for every time.  If no this will create a worktime exception.  Cancel to undo.", "Update Weekly Time?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
            Select Case ans
                Case Windows.Forms.DialogResult.Yes
                    rmvApt = e.SourceAppointment.RecurrencePattern
                    Dim strtDate, endDate, recStart, recEnd, tmps, tmpe As Date
                    tmps = emp.Days(pt.Day).StartTimes(pt.TimeRange)
                    tmpe = emp.Days(pt.Day).EndTimes(pt.TimeRange)
                    Dim sch As String = emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange)
                    Dim loc As String = emp.Days(pt.Day).Locations(pt.TimeRange)

                    strtDate = New Date(tmps.Year, tmps.Month, tmps.Day, apt.Start.Hour, apt.Start.Minute, apt.Start.Second)
                    endDate = New Date(tmpe.Year, tmpe.Month, tmpe.Day, apt.End.Hour, apt.End.Minute, apt.End.Second)
                    recStart = e.SourceAppointment.RecurrenceInfo.Start
                    recEnd = e.SourceAppointment.RecurrenceInfo.End
                    emp.Days(pt.Day).RemoveTimeRange(pt.TimeRange)
                    'emp.Days(pt.Day).AddTimeRange(recStart, recEnd)
                    rmvApt.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    rmvApt.End = New Date(recStart.Year, recStart.Month, recStart.Day, endDate.Hour, endDate.Minute, 0)
                    rmvApt.RecurrenceInfo.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    rmvApt.RecurrenceInfo.End = New Date(recEnd.Year, recEnd.Month, recEnd.Day, endDate.Hour, endDate.Minute, 0)

                    emp.Days(pt.Day).AddTimeRange(strtDate, endDate, sch, loc)

                    e.SourceAppointment.BeginUpdate()
                    e.SourceAppointment.Start = apt.Start
                    e.SourceAppointment.End = apt.End

                    e.SourceAppointment.RecurrenceInfo.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
                    e.SourceAppointment.RecurrenceInfo.End = New Date(recEnd.Year, recEnd.Month, recEnd.Day, endDate.Hour, endDate.Minute, 0)
                    'apt.RestoreOccurrence()
                    e.SourceAppointment.EndUpdate()
                    RestoringAppointment = True
                    e.SourceAppointment.RestoreOccurrence()
                    RestoringAppointment = False
                    SetupWorkHourExceptions(rmvApt)
                    ShowNoCoverage()
                    e.Handled = True
                    e.Allow = False

                Case Windows.Forms.DialogResult.No


                    Dim trs As List(Of TimeRangeException) = (From te In emp.Days(pt.Day).TimeExceptions Where te.Day.Date = apt.Start.Date And te.TimeRange = pt.TimeRange And te.StartTime = e.SourceAppointment.Start And te.EndTime = e.SourceAppointment.End).ToList



                    For Each tre As TimeRangeException In trs
                        emp.Days(pt.Day).TimeExceptions.Remove(tre)
                    Next
                    Dim tr As TimeRangeException = New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange, emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange), emp.Days(pt.Day).Locations(pt.TimeRange))
                    emp.Days(pt.Day).TimeExceptions.Add(tr)
                    pt.TimeRangeException = tr
                    'apt.RestoreOccurrence()
                    e.EditedAppointment.CustomFields(TagField) = pt
                    e.SourceAppointment.CustomFields(TagField) = pt
                    ShowNoCoverage()
                Case Windows.Forms.DialogResult.Cancel

                    e.Allow = False
                    e.Handled = True

            End Select
        Else
            If Not pt.IsHoliday Then


                Dim trs As List(Of TimeRangeException) = (From te In emp.Days(pt.Day).TimeExceptions Where te.Day.Date = apt.Start.Date And te.TimeRange = pt.TimeRange And te.StartTime = e.SourceAppointment.Start And te.EndTime = e.SourceAppointment.End).ToList

                For Each tre As TimeRangeException In trs
                    emp.Days(pt.Day).TimeExceptions.Remove(tre)
                Next
                Dim tr As TimeRangeException = New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange, emp.Days(pt.Day).ScheduleEmployeeTypes(pt.TimeRange), emp.Days(pt.Day).Locations(pt.TimeRange), ExceptionTypes.Add)
                emp.Days(pt.Day).TimeExceptions.Add(tr)
                pt.TimeRangeException = tr
                'apt.RestoreOccurrence()
                e.EditedAppointment.CustomFields(TagField) = pt
                ShowNoCoverage()
            Else




                Dim hi As HolidayInfo = pt.Holiday
                hi.Day = e.EditedAppointment.Start
                If e.EditedAppointment.AllDay Then
                    hi.EndDate = Nothing
                Else
                    hi.EndDate = e.EditedAppointment.End.AddDays(-1)
                End If

                e.EditedAppointment.CustomFields(TagField) = pt
                employees.Holidays.Remove(hi)
                employees.Holidays.Add(hi)
                employees.Holidays.Sort()

                tmrRebuild.Enabled = True

            End If


        End If
        e.EditedAppointment.LabelId = e.SourceAppointment.LabelId

    End Sub
    Dim colorNoCover1 As Color = Color.Red
    Dim colorNoCover2 As Color = Color.Black

    Private Sub SchedulerControl1_CustomDrawTimeCell(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.CustomDrawObjectEventArgs) Handles SchedulerControl1.CustomDrawTimeCell
        Dim info As DevExpress.XtraScheduler.Drawing.SelectableIntervalViewInfo = CType(e.ObjectInfo, DevExpress.XtraScheduler.Drawing.SelectableIntervalViewInfo)
        If employees.Count = 0 OrElse info.Selected OrElse Not My.Settings.CheckNoCoverage OrElse Not UpdatedChart Then Return

        Dim work As DevExpress.XtraScheduler.TimeInterval = employees.WorkHours.DayToWorkingTimeInterval(info.Interval.Start)

        If SchedulerStorage1.GetAppointments(info.Interval).Count = 0 Then
            If work.Contains(info.Interval) AndAlso employees.WorkHours.IsWorkingDay(info.Interval.Start.Date) AndAlso work.Start.Date >= info.Interval.Start.Date Then

                Dim GradMode As System.Drawing.Drawing2D.LinearGradientMode
                If SchedulerControl1.ActiveViewType = XtraScheduler.SchedulerViewType.Timeline Then
                    GradMode = Drawing2D.LinearGradientMode.Vertical
                Else
                    GradMode = Drawing2D.LinearGradientMode.Horizontal
                End If
                Using brsh As New Drawing2D.LinearGradientBrush(info.Bounds, colorNoCover1, colorNoCover2, GradMode)
                    e.Graphics.FillRectangle(brsh, e.Bounds)

                End Using
                e.Handled = True
            End If
        End If
    End Sub



    Private Sub SchedulerControl1_EditAppointmentFormShowing(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.AppointmentFormEventArgs) Handles SchedulerControl1.EditAppointmentFormShowing

        Dim pt As PointTag = e.Appointment.CustomFields(TagField)
        If e.Appointment.AllDay Then
            e.Handled = True
            Return
        End If
        ShowHours(pt)
        e.Handled = True


    End Sub

    Private Sub SchedulerControl1_EditRecurrentAppointmentFormShowing(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.EditRecurrentAppointmentFormEventArgs) Handles SchedulerControl1.EditRecurrentAppointmentFormShowing
        Dim pt As PointTag = e.Appointment.CustomFields(TagField)
        ShowHours(pt)
        e.Handled = True

    End Sub

    Private Sub SchedulerControl1_InitAppointmentDisplayText(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.AppointmentDisplayTextEventArgs) Handles SchedulerControl1.InitAppointmentDisplayText
        If e.Appointment.AllDay Then
            e.ViewInfo.Options.ShowEndTime = False
            e.ViewInfo.Options.ShowStartTime = False

        End If

    End Sub





    Dim mnuAddTime As New DevExpress.Utils.Menu.DXMenuItem("Add time for ", AddressOf mnuAddTime_Click)
    Dim mnuAddHoliday As New DevExpress.Utils.Menu.DXMenuItem("Add holiday for ", AddressOf mnuAddHoliday_Click)

    Private Sub mnuAddTime_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        AddTimeException()

    End Sub
    Private Sub mnuAddHoliday_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        AddHoliday(False)

    End Sub

    Private Sub SchedulerControl1_PreparePopupMenu(ByVal sender As Object, ByVal e As XtraScheduler.PopupMenuShowingEventArgs) Handles SchedulerControl1.PopupMenuShowing
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.RestoreOccurrence)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.EditSeries)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.DeleteAppointment)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.LabelSubMenu)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.NewAppointment)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.NewRecurringAppointment)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.NewRecurringEvent)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.OpenAppointment)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.SplitAppointment)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.StatusSubMenu)
        e.Menu.RemoveMenuItem(XtraScheduler.SchedulerMenuItemId.AppointmentDragCopy)

        If bbtnAddTimeException.Visibility = XtraBars.BarItemVisibility.Always Then

            e.Menu.Items.Add(mnuAddTime)
        End If
        If bbtnAddHoliday.Visibility = XtraBars.BarItemVisibility.Always Then
            e.Menu.Items.Add(mnuAddHoliday)
            If bbtnAddTimeException.Visibility = XtraBars.BarItemVisibility.Always Then
                mnuAddHoliday.BeginGroup = False
            Else
                mnuAddHoliday.BeginGroup = True
            End If

        End If


    End Sub




    Private Sub SchedulerControl1_QueryWorkTime(ByVal sender As System.Object, ByVal e As XtraScheduler.QueryWorkTimeEventArgs) Handles SchedulerControl1.QueryWorkTime
        With employees.WorkHours
            Select Case e.Interval.Start.DayOfWeek
                Case DayOfWeek.Sunday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.SundayStartHour, .SundayStartMinute, 0), New TimeSpan(.SundayEndHour, .SundayEndMinute, 0))
                Case DayOfWeek.Monday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.MondayStartHour, .MondayStartMinute, 0), New TimeSpan(.MondayEndHour, .MondayEndMinute, 0))
                Case DayOfWeek.Tuesday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.TuesdayStartHour, .TuesdayStartMinute, 0), New TimeSpan(.TuesdayEndHour, .TuesdayEndMinute, 0))
                Case DayOfWeek.Wednesday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.WednesdayStartHour, .WednesdayStartMinute, 0), New TimeSpan(.WednesdayEndHour, .WednesdayEndMinute, 0))
                Case DayOfWeek.Thursday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.ThursdayStartHour, .ThursdayStartMinute, 0), New TimeSpan(.ThursdayEndHour, .ThursdayEndMinute, 0))
                Case DayOfWeek.Friday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.FridayStartHour, .FridayStartMinute, 0), New TimeSpan(.FridayEndHour, .FridayEndMinute, 0))
                Case DayOfWeek.Saturday
                    e.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(.SaturdayStartHour, .SaturdayStartMinute, 0), New TimeSpan(.SaturdayEndHour, .SaturdayEndMinute, 0))
            End Select
        End With
        Dim exc As WorkHoursSettings.HourSettingException = (From ex In employees.WorkHours.SettingsExceptions Where ex.ExceptionDate = e.Interval.Start.Date).FirstOrDefault
        If exc IsNot Nothing Then e.WorkTime = exc.ToTimeOfDayInterval

    End Sub


    Private Sub SchedulerStorage1_AppointmentChanging(ByVal sender As Object, ByVal e As XtraScheduler.PersistentObjectCancelEventArgs) Handles SchedulerStorage1.AppointmentChanging
        'debugLogWithStack(logger, "Appointment Changing:" & e.Object.GetRow(SchedulerStorage1).ToString)
        'Static IsChanging As Boolean = False
        'If Not IsChanging Then
        '    IsChanging = True
        'Else
        '    Return
        'End If
        'Dim apt As XtraScheduler.Appointment = e.Object
        '' Stop
        'Dim emp As Employee = apt.ResourceId

        'Dim rmvApt As XtraScheduler.Appointment
        'Select Case apt.Type
        '    Case XtraScheduler.AppointmentType.ChangedOccurrence
        '        Dim pt As PointTag = apt.CustomFields(TagField)
        '        Dim ans As DialogResult = XtraEditors.XtraMessageBox.Show("Do you want to update this series?  If you do the slected day's worktime will be adjusted for every time.  If no this will create a worktime exception.  Cancel to undo.", "Update Weekly Time?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
        '        Select Case ans
        '            Case Windows.Forms.DialogResult.Yes
        '                rmvApt = apt.RecurrencePattern
        '                Dim strtDate, endDate, recStart, recEnd As Date
        '                strtDate = apt.Start
        '                endDate = apt.End
        '                recStart = apt.RecurrenceInfo.Start
        '                recEnd = apt.RecurrenceInfo.End
        '                emp.Days(pt.Day).RemoveTimeRange(pt.TimeRange)
        '                emp.Days(pt.Day).AddTimeRange(apt.Start, apt.End)

        '                apt.RestoreOccurrence()
        '                rmvApt.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
        '                rmvApt.End = New Date(recStart.Year, recStart.Month, recStart.Day, endDate.Hour, endDate.Minute, 0)
        '                rmvApt.RecurrenceInfo.Start = New Date(recStart.Year, recStart.Month, recStart.Day, strtDate.Hour, strtDate.Minute, 0)
        '                rmvApt.RecurrenceInfo.End = New Date(recEnd.Year, recEnd.Month, recEnd.Day, endDate.Hour, endDate.Minute, 0)

        '            Case Windows.Forms.DialogResult.No

        '                Dim trs As New List(Of TimeRangeException)

        '                For Each tre As TimeRangeException In emp.Days(pt.Day).TimeExceptions
        '                    If tre.Day.Date = apt.Start.Date Then trs.Add(tre)
        '                Next
        '                For Each tre As TimeRangeException In trs
        '                    emp.Days(pt.Day).TimeExceptions.Remove(tre)
        '                Next
        '                emp.Days(pt.Day).TimeExceptions.Add(New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange))

        '                'apt.RestoreOccurrence()

        '            Case Windows.Forms.DialogResult.Cancel
        '                'IsChanging = False
        '                'apt.RestoreOccurrence()
        '                e.Cancel = True
        '                e.Object.CancelUpdate()
        '                'apt.RecurrencePattern.RestoreOccurrence()
        '                'e.Object.CancelUpdate()

        '        End Select
        '    Case XtraScheduler.AppointmentType.Normal
        '        e.Cancel = True
        'End Select

        'IsChanging = False
    End Sub




    Private Sub SchedulerStorage1_AppointmentDeleting(ByVal sender As Object, ByVal e As DevExpress.XtraScheduler.PersistentObjectCancelEventArgs) Handles SchedulerStorage1.AppointmentDeleting
        If RestoringAppointment Then Return
        Dim apt As XtraScheduler.Appointment = e.Object

        Dim pt As PointTag = apt.CustomFields(TagField)
        If pt.TimeRangeException IsNot Nothing AndAlso pt.TimeRangeException.ExceptionType = ExceptionTypes.Replace Then
            e.Cancel = True
            pt.Employee.Days(pt.Day).TimeExceptions.Remove(pt.TimeRangeException)
            pt.TimeRangeException = Nothing
            Me.BeginInvoke(Sub()
                               RestoringAppointment = True
                               SchedulerControl1.SelectedAppointments(0).RestoreOccurrence()

                               RestoringAppointment = False
                           End Sub)
            Return
        ElseIf pt.IsHoliday Then


            Dim hol As HolidayInfo = pt.Holiday
            If hol.IsGeneralHoliday Then
                employees.Holidays.Remove(hol)
                e.Cancel = False
                DeletedHoliday = True

            Else
                e.Cancel = True
            End If

        End If

        e.Cancel = XtraEditors.XtraMessageBox.Show("Are you sure you want to delete the """ & apt.Subject & """ appointment starting at " & apt.Start.ToShortDateString & " " & apt.Start.ToShortTimeString & "?", "Delete Employee Hours", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.No

        'todo fix so no duplicate ask to delete same appointment and also to ignore deleted appointments because the appointment is being resized or moved.


        If Not e.Cancel Then

            Try


                If pt.IsHoliday Then
                    Dim hol As HolidayInfo = pt.Holiday
                    pt.Employee.Holidays.Remove(hol)
                    If hol.IsGeneralHoliday Then
                        For Each emptmp In employees
                            emptmp.Holidays.Remove(hol)

                        Next
                        employees.Holidays.Remove(hol)
                    End If

                    Return
                End If
            Catch ex As Exception

            End Try

        End If
        Dim aptType As DevExpress.XtraScheduler.AppointmentType = SchedulerStorage1.GetObjectValue(e.Object, "Type")
        Dim emp As Employee = pt.Employee
        Dim te As New TimeRangeException(apt.Start.Date, apt.Start, apt.End, pt.TimeRange, "", "", ExceptionTypes.Delete)
        If emp IsNot Nothing AndAlso pt.TimeRangeException Is Nothing AndAlso RestoringAppointment = False Then emp.Days(pt.Day).TimeExceptions.Add(te)


    End Sub

    Private Sub SchedulerStorage1_AppointmentsChanged(ByVal sender As Object, ByVal e As XtraScheduler.PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsChanged
        'UpdateChart()
        'For Each apt As XtraScheduler.Appointment In e.Objects
        '    ' Stop

        'Next
        'UpdateChart()
        For Each obj As Object In e.Objects
            Debug.WriteLine(GetType(Object).FullName)

        Next
        'If Not InUpdateChart Then ShowNoCoverage()

    End Sub
    Private ChangeSkin As Boolean = False
    Public Sub New()
        Try
            Dim instalType As InstallTypes = [Enum].Parse(GetType(InstallTypes), My.Settings.InstallType)

            If instalType = InstallTypes.MSI Then
                Dim di As IO.DirectoryInfo = IO.Directory.CreateDirectory(IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "VBJay Solutions\Employee Scheduler"))

                EmpFile = IO.Path.Combine(di.FullName, My.Resources.EmployeeData)

            End If
        Catch ex As Exception

        End Try


        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        DefaultLookAndFeel1.LookAndFeel.SkinName = My.Settings.FormTheme
        SetCaptionColor()
        mnuAddTime.BeginGroup = True
        mnuAddTime.Image = My.Resources.AddTime16
        mnuAddHoliday.Image = My.Resources.AddHoliday16
    End Sub

    Private Sub optgChartType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optgChartType.SelectedIndexChanged
        RefreshData()
    End Sub

    Private Sub cboLayoutTheme_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboLayoutTheme.SelectedIndexChanged
        If cboLayoutTheme.SelectedIndex = -1 Then Return

        If ChangeSkin Then
            Me.DefaultLookAndFeel1.LookAndFeel.SkinName = cboLayoutTheme.SelectedItem
            SetCaptionColor()
            DevExpress.LookAndFeel.LookAndFeelHelper.ForceDefaultLookAndFeelChanged()
            Me.Invalidate()
        End If
        My.Settings.FormTheme = cboLayoutTheme.SelectedItem


    End Sub



    Private Sub frmEmployees_HelpButtonClicked(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.HelpButtonClicked
        Dim abt As New AboutBox
        abt.ShowDialog()
        e.Cancel = True

    End Sub

    Private Sub cboGroup_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboGroup.SelectedIndexChanged
        If cboGroup.SelectedIndex = -1 Then cboGroup.SelectedIndex = 0
        SchedulerControl1.GroupType = cboGroup.SelectedIndex
        My.Settings.CalendarGrouping = SchedulerControl1.GroupType
    End Sub


    Private Sub RefreshData()
        SchedulerControl1.Invalidate()
        Me.UseWaitCursor = True

        Application.DoEvents()

        SchedulerControl1.BeginUpdate()





        SetupChart()
        SetupLabels()
        UpdateChart()

        Try
            SchedulerControl1.EndUpdate()

        Catch ex As Exception
        Finally
            Me.UseWaitCursor = False
            Application.DoEvents()
            Me.Cursor = Cursors.Default
        End Try




    End Sub

    Private Sub ApplyWorkHours(ByRef HourSettings As WorkHoursSettings)

        SchedulerControl1.WorkDays.BeginUpdate()
        SchedulerControl1.WorkDays.Clear()
        If HourSettings.SemesterEnd <> dtRangeEnd.DateTime OrElse HourSettings.SemesterStart <> dtRangeStart.DateTime Then
            HourSettings.SemesterStart = dtRangeStart.DateTime
            HourSettings.SemesterEnd = dtRangeEnd.DateTime
            If HaveSetupChart Then
                'UpdateChart()

            End If

        End If

        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Sunday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Sunday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Monday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Monday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Tuesday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Tuesday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Wednesday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Wednesday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Thursday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Thursday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Friday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Friday)
        If HourSettings.DaysToWork And WorkHoursSettings.WorkingDays.Saturday Then SchedulerControl1.WorkDays.Add(XtraScheduler.WeekDays.Saturday)



        SchedulerControl1.WorkWeekView.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(HourSettings.GetSmallestWorkingHour, HourSettings.GetSmallestWorkingMinute, 0), New TimeSpan(HourSettings.GetLargestWorkingHour, HourSettings.GetLargestWorkingMinute, 0))
        SchedulerControl1.DayView.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(HourSettings.GetSmallestWorkingHour, HourSettings.GetSmallestWorkingMinute, 0), New TimeSpan(HourSettings.GetLargestWorkingHour, HourSettings.GetLargestWorkingMinute, 0))
        SchedulerControl1.TimelineView.WorkTime = New XtraScheduler.TimeOfDayInterval(New TimeSpan(HourSettings.GetSmallestWorkingHour, HourSettings.GetSmallestWorkingMinute, 0), New TimeSpan(HourSettings.GetLargestWorkingHour, HourSettings.GetLargestWorkingMinute, 0))

        If SchedulerControl1.WorkWeekView.WorkTime.Start >= TimeSpan.FromMinutes(30) Then
            SchedulerControl1.WorkWeekView.WorkTime.Start = SchedulerControl1.WorkWeekView.WorkTime.Start.Subtract(TimeSpan.FromMinutes(30))
        End If


        If SchedulerControl1.DayView.WorkTime.Start >= TimeSpan.FromMinutes(30) Then
            SchedulerControl1.DayView.WorkTime.Start = SchedulerControl1.DayView.WorkTime.Start.Subtract(TimeSpan.FromMinutes(30))
        End If


        If SchedulerControl1.TimelineView.WorkTime.Start >= TimeSpan.FromMinutes(30) Then
            SchedulerControl1.TimelineView.WorkTime.Start = SchedulerControl1.TimelineView.WorkTime.Start.Subtract(TimeSpan.FromMinutes(30))
        End If

        If SchedulerControl1.WorkWeekView.WorkTime.End <= New TimeSpan(23, 30, 0) Then
            SchedulerControl1.WorkWeekView.WorkTime.End = SchedulerControl1.WorkWeekView.WorkTime.End.Add(TimeSpan.FromMinutes(30))
        End If


        If SchedulerControl1.DayView.WorkTime.End <= New TimeSpan(23, 30, 0) Then
            SchedulerControl1.DayView.WorkTime.End = SchedulerControl1.DayView.WorkTime.End.Add(TimeSpan.FromMinutes(30))
        End If


        If SchedulerControl1.TimelineView.WorkTime.End <= New TimeSpan(23, 30, 0) Then
            SchedulerControl1.TimelineView.WorkTime.End = SchedulerControl1.TimelineView.WorkTime.End.Add(TimeSpan.FromMinutes(30))
        End If

        If employees IsNot Nothing Then


            For Each hi As HolidayInfo In From h In employees.Holidays Where h.IsGeneralHoliday = True
                Dim h As Schedule.Holiday
                h = SchedulerControl1.WorkDays(SchedulerControl1.WorkDays.AddHoliday(hi.Day, hi.Caption))
                Dim apt As XtraScheduler.Appointment = DevExpress.XtraScheduler.Native.HolidaysHelper.CreateHolidayAppointment(h, SchedulerStorage1)
                Dim pt As New PointTag(-1, -1)
                pt.IsHoliday = True
                pt.Holiday = hi
                apt.CustomFields(TagField) = pt


                If hi.EndDate.HasValue Then
                    'Dim dt As Date = hi.Day.Date.AddDays(1)
                    'Do While dt <= hi.EndDate.Value.Date
                    '    h = SchedulerControl1.WorkDays(SchedulerControl1.WorkDays.AddHoliday(hi.Day, hi.Caption))
                    '    DevExpress.XtraScheduler.Native.HolidaysHelper.CreateHolidayAppointment(h, SchedulerStorage1)

                    '    dt = dt.AddDays(1)

                    'Loop
                    apt.End = hi.EndDate.Value.AddDays(1)

                End If
                SchedulerStorage1.Appointments.Add(apt)
            Next
        End If


        SchedulerControl1.LimitInterval = New DevExpress.XtraScheduler.TimeInterval(HourSettings.SemesterStart, New Date(HourSettings.SemesterEnd.Year, HourSettings.SemesterEnd.Month, HourSettings.SemesterEnd.Day, 23, 59, 0))
        dtChartView.Properties.MinValue = SchedulerControl1.LimitInterval.Start.Date
        dtChartView.Properties.MaxValue = SchedulerControl1.LimitInterval.End.Date
        SchedulerControl1.WorkDays.EndUpdate()

    End Sub


    Private Sub btnApplyWorkHours_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnApplyWorkHours.Click
        employees.WorkHours = WorkHoursControl1.HourSettings
        employees.RemoveSchedulesOutofWorkTime()
        RefreshData()
        lbEmployees.Focus()
        dpWorkHours.Hide()

    End Sub



    Private Sub dpWorkHours_Container_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dpWorkHours_Container.VisibleChanged
        If dpWorkHours_Container.Visible Then
            WorkHoursControl1.HourSettings = employees.WorkHours
            dtRangeStart.DateTime = employees.WorkHours.SemesterStart
            dtRangeEnd.DateTime = employees.WorkHours.SemesterEnd
            WorkHoursControl1.Invalidate()


        End If
    End Sub



    Private Sub frmEmployees_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        HaveSetupChart = True
        bwCheckUpdate.RunWorkerAsync()
        ApplyWorkHours(employees.WorkHours)

        RefreshData()
    End Sub

    Private Sub bbtnImportKey_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnImportKey.ItemClick
        Dim title As String = ofdEmployee.Title
        ofdEmployee.Title = "Import Boss Key"
        ofdEmployee.FileName = "Boss.key"
        If ofdEmployee.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                Dim doc As New Xml.XmlDocument
                doc.Load(ofdEmployee.FileName)
                My.Settings.BossPublicKey = doc.OuterXml
            Catch ex As Exception
                My.Settings.BossPublicKey = ""
                XtraEditors.XtraMessageBox.Show("Failed to import Boss key.  Boss key was cleared." & vbCrLf & ex.ToString, "Can't Import Key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)


            End Try



        End If
    End Sub

    Private Sub bbtnAddEmployee_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnAddEmployee.ItemClick
        Dim name As String = InputBox("Please enter the name of the employee?")
        If String.IsNullOrEmpty(name) Then
            XtraEditors.XtraMessageBox.Show("You must enter a name to create an employee.", "Can't Create Employee With No Name", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return

        End If

        Dim emp As New Employee(name)
        If employees.Count > 0 Then
            Dim holidays As IEnumerable(Of HolidayInfo) = From hi As HolidayInfo In employees(0).Holidays Where hi.IsGeneralHoliday = True
            emp.Holidays.AddRange(holidays)
        End If
        employees.Add(emp)
        'emp.Days(1).AddTimeRange(New Date (0,0,0,7,30,0),New Date (0,0,0,14,0,0)

        employees.Sort()
        lbEmployees.Items.Clear()
        lbEmployees.Items.AddRange(employees.ToArray)
        UpdateEnabled()
        RefreshData()
    End Sub

    Private Sub bbtnModifyEmployee_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnModifyEmployee.ItemClick
        ShowHours()
    End Sub

    Private Sub bbtnPrintCharts_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnPrintCharts.ItemClick


        chrtHours.Printing.PrintDocument.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)

        chrtHours.Printing.PrintPreview()
        RefreshData()
    End Sub

    Private Sub bbtnPrintCalendar_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnPrintCalendar.ItemClick
        SchedulerControl1.ShowPrintOptionsForm()
    End Sub

    Private Sub bbtnLoad_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnLoad.ItemClick
        ofdEmployee.FileName = "employees.xml"
        If ofdEmployee.ShowDialog = Windows.Forms.DialogResult.OK Then
            Dim emps As EmployeeList = EmployeeList.LoadEmployees(ofdEmployee.FileName)
            If emps.Count = 0 Then
                XtraEditors.XtraMessageBox.Show("The selected file either was not a valid employee schedule data file or it is empty.  Please select a different file.", "No Data", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Return
            End If
            Dim empLoad As New frmLoadEmployees(emps, ofdEmployee.FileName)

            If empLoad.ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then Return
            Dim empResult As IEnumerable(Of Employee) = From em In employees _
                                                   Join emp In empLoad.EmployeesToLoad On em.ID Equals emp.ID Select em
            Dim empResultNames As IEnumerable(Of Employee) = From em In employees _
                                                   Join emp In empLoad.EmployeesToLoad On em.Name Equals emp.Name And em.EmployeeType Equals emp.EmployeeType Select em
            If empLoad.DoMerge Then
                Dim rmv As New EmployeeList
                If empLoad.MergeType = frmLoadEmployees.MergeTypes.Name Then
                    rmv.AddRange(empResultNames)
                Else
                    rmv.AddRange(empResult)
                End If

                For Each em As Employee In rmv
                    employees.Remove(em)

                Next
                employees.AddRange(empLoad.EmployeesToLoad)
                employees.Holidays = empLoad.EmployeesToLoad.Holidays
            Else
                employees = empLoad.EmployeesToLoad

            End If
            employees.WorkHours = emps.WorkHours
            employees.Filters = emps.Filters
            employees.ScheduleColors = emps.ScheduleColors
            dtRangeStart.DateTime = emps.WorkHours.SemesterStart
            dtRangeEnd.DateTime = emps.WorkHours.SemesterEnd


            'If Not String.IsNullOrEmpty(My.Settings.BossPublicKey) Then
            '    If Not empLoad.DoMerge AndAlso employees.Boss.VerifySignature(ofdEmployee.FileName, My.Settings.BossPublicKey) Then
            '        Me.Text = "Employee Scheduler [Official Schedule]"
            '    Else
            '        Me.Text = "Employee Scheduler"

            '    End If
            'End If

            employees.Sort()
            lbEmployees.Items.Clear()
            lbEmployees.Items.AddRange(employees.ToArray)
            LoadFilters()
            UpdateEnabled()
            RefreshData()
        End If
    End Sub

    Private Sub bbtnSaveData_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnSaveData.ItemClick
        sfdEmployee.FileName = "employees.xml"
        If sfdEmployee.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                employees.Save(sfdEmployee.FileName, True)
            Catch ex As Exception
                logger.LogException(NLog.LogLevel.Debug, "Failed to save employee data.", ex)
                XtraEditors.XtraMessageBox.Show("Failed to save employee data." & vbCrLf & ex.ToString, "Can't Save Data", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

            End Try


        End If
    End Sub

    Private Sub bbtnExportKey_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnExportKey.ItemClick
        Dim title As String = sfdEmployee.Title
        sfdEmployee.FileName = "Boss.key"
        sfdEmployee.Title = "Save Boss Key"


        If sfdEmployee.ShowDialog = Windows.Forms.DialogResult.OK Then

            Try
                employees.Boss.SavePublicKey(sfdEmployee.FileName)
            Catch ex As Exception
                XtraEditors.XtraMessageBox.Show("Failed to save boss key." & vbCrLf & ex.ToString, "Can't Export Boss Key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

            End Try



        End If
        sfdEmployee.Title = title
    End Sub

    Private Sub bbtnRemoveEmployee_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnRemoveEmployee.ItemClick
        If lbEmployees.SelectedItem Is Nothing Then Return
        employees.Remove(lbEmployees.SelectedItem)
        lbEmployees.Items.Remove(lbEmployees.SelectedItem)
        If lbEmployees.Items.Count >= 1 Then lbEmployees.SelectedIndex = 0

        UpdateEnabled()
        UpdateChart()
    End Sub

    Private Sub bchkIncludeHours_ItemClick(ByVal sender As System.Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bchkIncludeHours.ItemClick
        bchkIncludeHours.EditValue = Not bchkIncludeHours.EditValue

    End Sub

    Private Sub bchkGrayScale_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bchkGrayScale.ItemClick
        bchkGrayScale.EditValue = Not bchkGrayScale.EditValue
    End Sub

    Private Sub ViewNavigatorRibbonPageGroup1_CaptionButtonClick(ByVal sender As System.Object, ByVal e As XtraBars.Ribbon.RibbonPageGroupEventArgs) Handles ViewNavigatorRibbonPageGroup1.CaptionButtonClick
        SchedulerControl1.ShowGotoDateForm()
    End Sub

    Private Sub lbEmployees_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lbEmployees.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Right Then
            Dim p As New Point(e.Location.X, e.Location.Y)
            p.Offset(50, 100)
            pmnuData.ShowPopup(p)

        End If
    End Sub

    Private Sub bbtnClearEmployeeData_ItemClick(ByVal sender As Object, ByVal e As XtraBars.ItemClickEventArgs) Handles bbtnClearEmployeeData.ItemClick
        If XtraEditors.XtraMessageBox.Show("Are you sure you want to delete all employee data(Work Times, Holidays, and Work Time Exceptions)?  This will leave you with just the employees.", "Clear All Employee Data", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
            For Each emp As Employee In employees
                For Each dy As Day In emp.Days
                    dy.Clear()

                Next
                emp.Holidays.Clear()

            Next
            employees.Holidays.Clear()
            LoadFilters()
            RefreshData()
        End If
    End Sub

    Private Sub bbtnClearEmployees_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnClearEmployees.ItemClick
        If XtraEditors.XtraMessageBox.Show("Are you sure you want to delete all employees?", "Clear All Employees", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
            Dim settings As WorkHoursSettings = employees.WorkHours
            employees = New EmployeeList
            employees.WorkHours = settings
            lbEmployees.Items.Clear()
            RefreshData()

        End If

    End Sub

    Private Sub bbtnClearGeneralHolidays_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnClearGeneralHolidays.ItemClick
        If XtraEditors.XtraMessageBox.Show("Are you sure you want to delete all [All Employee] holidays?", "Clear All Employee Holidays", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then

            Dim hols As List(Of HolidayInfo) = (From hi In employees.Holidays Where hi.IsGeneralHoliday = True).ToList
            For Each hi As HolidayInfo In hols
                employees.Holidays.Remove(hi)
            Next


        End If

    End Sub

    Private Sub lbEmployees_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lbEmployees.MouseDown
        If lbEmployees.IndexFromPoint(e.Location) <> -1 Then
            lbEmployees.SelectedIndex = lbEmployees.IndexFromPoint(e.Location)

        End If
    End Sub
    Dim noCoverTimes As New List(Of DevExpress.XtraScheduler.TimeInterval)
    Private Sub ShowNoCoverage()
        If Not My.Settings.CheckNoCoverage OrElse employees.Count = 0 Then Return

        Dim fc As New DevExpress.XtraScheduler.Tools.FreeTimeCalculator(Me.SchedulerStorage1)

        Dim int As New DevExpress.XtraScheduler.TimeInterval
        Dim hours As WorkHoursSettings = employees.WorkHours

        Dim currentDay As Date = hours.SemesterStart

        lbCoverage.Items.Clear()
        noCoverTimes.Clear()
        Do While currentDay <= hours.SemesterEnd
            If hours.IsWorkingDay(currentDay) Then
                int = hours.DayToWorkingTimeInterval(currentDay)
                Dim freetimes As DevExpress.XtraScheduler.TimeIntervalCollection = fc.CalculateFreeTime(int)
                For Each ft As DevExpress.XtraScheduler.TimeInterval In freetimes
                    lbCoverage.Items.Add(ft.Start.Date.ToShortDateString)
                    noCoverTimes.Add(ft)

                Next


            End If


            currentDay = currentDay.AddDays(1)

        Loop
        If lbCoverage.ItemCount >= 1 Then
            ' dpNoCoverage.Appearance.Font = New Font(dpNoCoverage.Font, FontStyle.Bold)
            dpNoCoverage.Text = "No Coverage(" & lbCoverage.ItemCount.ToString & ")"
            ' XtraEditors.XtraMessageBox.Show("There are times where nobody is working.  Please check the times in the No Coverage Pane.", "No Coverage Alert", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Alerter.Show(Me, "No Coverage", "There are times where nobody is working.  Please check the times in the No Coverage Pane.")
            'dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.Visible
            ' dpNoCoverage.Show()

            ' lbCoverage.Focus()
        Else
            ' dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.AutoHide
            dpNoCoverage.Appearance.Font = New Font(dpNoCoverage.Font, FontStyle.Regular)
            dpNoCoverage.Text = "No Coverage"

        End If






    End Sub



    Private Sub lbCoverage_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lbCoverage.MouseUp
        Dim item As Integer = lbCoverage.IndexFromPoint(e.Location)
        If item >= 0 Then
            Dim dt As Date = Date.Parse(lbCoverage.Items(item))
            SchedulerControl1.Start = dt

        End If
    End Sub

    'Private Sub lbCoverage_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbCoverage.SelectedIndexChanged
    '    If lbCoverage.SelectedIndex >= 0 Then
    '        Dim dt As Date = Date.Parse(lbCoverage.Items(lbCoverage.SelectedIndex))
    '        SchedulerControl1.Start = dt
    '        'Dim int As DevExpress.XtraScheduler.TimeInterval = noCoverTimes(lbCoverage.SelectedIndex)


    '    End If
    'End Sub

    Private Sub chkCheckCoverage_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkCheckCoverage.CheckedChanged
        lbCoverage.Items.Clear()
        If chkCheckCoverage.Checked Then
            dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.AutoHide
            ShowNoCoverage()
        Else
            dpNoCoverage.Visibility = XtraBars.Docking.DockVisibility.Hidden
        End If


    End Sub


    Private Function GetNoCoverageImage(ByVal rect As Rectangle) As System.Drawing.Image
        Dim bmp As New Bitmap(rect.Width, rect.Height, Imaging.PixelFormat.Format32bppRgb)
        Using g As Graphics = Graphics.FromImage(bmp)


            Using brsh As New Drawing2D.LinearGradientBrush(rect, colorNoCover1, colorNoCover2, Drawing2D.LinearGradientMode.Horizontal)
                g.FillRectangle(brsh, rect)

            End Using
        End Using
        Return bmp
    End Function

    Private Sub imgNoCoverage_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles imgNoCoverage.Resize
        imgNoCoverage.Image = GetNoCoverageImage(New Rectangle(0, 0, imgNoCoverage.Width, imgNoCoverage.Height))


    End Sub


    Private Sub SchedulerControl1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles SchedulerControl1.SelectionChanged
        UpdateEnabled()
        Dim status As String = ""
        If SchedulerControl1.SelectedAppointments.Count = 0 Then
            ShowStatus("")
        Else
            Dim apt As XtraScheduler.Appointment = SchedulerControl1.SelectedAppointments(0)
            Dim pt As PointTag = apt.CustomFields(TagField)

            If pt.IsHoliday Then
                ShowStatus(String.Format("{0} All Employee Holiday.  Press the Delete key to remove this holiday.", pt.Holiday.Caption))
            Else
                Dim emp As Employee = apt.ResourceId
                If pt.TimeRangeException IsNot Nothing Then
                    Dim tex As TimeRangeException = pt.TimeRangeException

                    Select Case tex.ExceptionType
                        Case ExceptionTypes.Add
                            status = String.Format("{0} is working from {1} to {2} on {3} when they normally do not work. Press the delete key to remove this work time.", emp.Name, apt.Start.ToShortTimeString, apt.End.ToShortTimeString, apt.Start.ToShortDateString)
                        Case ExceptionTypes.Replace
                            Dim st, en, stO, enO As Date
                            st = tex.StartTime
                            en = tex.EndTime
                            stO = pt.Employee.Days(tex.Day.DayOfWeek).StartTimes(tex.TimeRange)
                            enO = pt.Employee.Days(tex.Day.DayOfWeek).EndTimes(tex.TimeRange)
                            status = String.Format("{0} is working from {1} to {2} on {3} instead of {4} to {5}. Press the delete key to reset to the regular working time.", emp.Name, st.ToShortTimeString, en.ToShortTimeString, st.ToShortDateString, stO.ToShortTimeString, enO.ToShortTimeString)

                    End Select
                    If pt.WorkSettingException IsNot Nothing Then
                        Dim wex As WorkHoursSettings.HourSettingException = pt.WorkSettingException
                        status &= String.Format("  Work time has been changed because the building hours have changed on {0}.", wex.ExceptionDate.ToShortDateString)
                    End If
                    ShowStatus(status)
                Else
                    status = String.Format("{0} is working from {1} to {2} on {3}.  Press delete to remove the work time from {4} only.", emp.Name, apt.Start.ToShortTimeString, apt.End.ToShortTimeString, apt.Start.ToShortDateString, apt.Start.ToShortDateString)
                    If pt.WorkSettingException IsNot Nothing Then
                        Dim wex As WorkHoursSettings.HourSettingException = pt.WorkSettingException
                        status &= String.Format("  Work time has been changed because the building hours have changed on {0}.", wex.ExceptionDate.ToShortDateString)
                    End If
                    ShowStatus(status)
                End If

            End If

        End If



    End Sub


    Private Sub WorkHoursControl1_ExceptionsChanged(ByVal Sender As Object, ByVal e As System.EventArgs) Handles WorkHoursControl1.ExceptionsChanged

        RefreshData()
    End Sub

    Private Sub dtChartView_EditValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtChartView.EditValueChanged
        If HaveSetupChart Then
            SchedulerControl1.BeginUpdate()
            SetupChart()
            UpdateChart()
            SchedulerControl1.EndUpdate()
        End If

    End Sub
    Private Sub AddHoliday(ByVal AllEmployee As Boolean)
        Dim ti As XtraScheduler.TimeInterval = SchedulerControl1.SelectedInterval
        Dim st As Date
        Dim en As Date?
        st = ti.Start.Date
        en = ti.End.Date
        If ti.Duration = TimeSpan.FromDays(1) Then
            en = Nothing
        Else
            en = en.Value.AddDays(-1)
        End If
        If lbEmployees.SelectedIndex <> -1 Then

            Dim emp As Employee = employees(lbEmployees.SelectedIndex)
            If AllEmployee Then
                employees.Holidays.Add(New HolidayInfo(st, en, InputBox("Please enter a description or reason for this holiday?", "Holiday Caption"), True))
            Else
                emp.Holidays.Add(New HolidayInfo(st, en, InputBox("Please enter a description or reason for this holiday?", "Holiday Caption"), False))
            End If
        End If
        RefreshData()

    End Sub
    Private Sub AddTimeException()
        Dim ti As XtraScheduler.TimeInterval = SchedulerControl1.SelectedInterval
        Dim emp As Employee = employees(lbEmployees.SelectedIndex)
        Dim tre As New TimeRangeException(ti.Start.Date, ti.Start, ti.End, -1, InputBox("Enter Schedule Type for this exception.", "Schedule Type", emp.EmployeeType), emp.DefaultLocation, ExceptionTypes.Add)
        emp.Days(ti.Start.DayOfWeek).TimeExceptions.Add(tre)

        RefreshData()
    End Sub
    Private Sub bbtnAddTimeException_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnAddTimeException.ItemClick
        AddTimeException()

    End Sub

    Private Sub bbtnAddAllHoliday_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnAddAllHoliday.ItemClick
        AddHoliday(True)
    End Sub

    Private Sub bbtnAddHoliday_ItemClick(ByVal sender As System.Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnAddHoliday.ItemClick
        AddHoliday(False)
    End Sub

    Private Sub Alerter_BeforeFormShow(ByVal sender As Object, ByVal e As DevExpress.XtraBars.Alerter.AlertFormEventArgs) Handles Alerter.BeforeFormShow
        For Each frm As DevExpress.XtraBars.Alerter.AlertForm In Alerter.AlertFormList
            If frm IsNot e.AlertForm Then frm.Close()
        Next
    End Sub

    Private Sub tmrRebuild_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRebuild.Tick
        tmrRebuild.Enabled = False
        logger.Debug("tmrRebuild tick")
        SchedulerControl1.BeginUpdate()
        RefreshData()
        SchedulerControl1.EndUpdate()

    End Sub

    Private Sub chkCalculateHours_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkCalculateHours.CheckedChanged
        RefreshData()

    End Sub



    Private Sub chrtHourNumbers_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chrtHourNumbers.Click
        XtraTabControl1.Focus()
    End Sub

    Private Sub bwCheckUpdate_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwCheckUpdate.DoWork
        Dim url As Uri = Nothing
        If Not CheckNewRelease(url) Then
            url = Nothing
        End If
        e.Result = url


    End Sub
    Delegate Sub dShowUpdate(ByVal URL As Uri)

    Private Sub ShowUpdate(ByVal URL As Uri)
        barUpdateLink.Tag = URL.AbsoluteUri

        barUpdateLink.Visibility = XtraBars.BarItemVisibility.Always
        Dim toast As New ToastForm(7000, "There is a new release on codeplex.com")
        toast.UpdateUrl = URL

        toast.Show()


    End Sub
    Private Sub bwCheckUpdate_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwCheckUpdate.RunWorkerCompleted
        If Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then Return
        If My.Computer.Network.IsAvailable Then
            Dim url As Uri = e.Result
            Try
                If url IsNot Nothing Then ShowUpdate(url)

            Catch ex As Exception

            End Try
        End If


    End Sub



    Private Sub barUpdateLink_ItemClick(ByVal sender As System.Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles barUpdateLink.ItemClick
        Try
            'If XtraEditors.XtraMessageBox.Show("There is a new release on codeplex.  Would you like to go to the release page?", "New Release", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) = Windows.Forms.DialogResult.Yes Then
            Process.Start(barUpdateLink.Tag)


        Catch ex As Exception

        End Try
    End Sub

    Private Sub barTestUpdate_ItemClick(ByVal sender As System.Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles barTestUpdate.ItemClick
        Dim url As New Uri(My.Settings.ProjectWebsite)
        ShowUpdate(url)
    End Sub

    Private Sub RibbonStatusBar1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RibbonStatusBar1.MouseMove
        Dim hi As XtraBars.Ribbon.ViewInfo.RibbonHitInfo = RibbonStatusBar1.CalcHitInfo(e.Location)
        If hi.HitTest = XtraBars.Ribbon.ViewInfo.RibbonHitTest.Item AndAlso hi.Item.Item.Id = barUpdateLink.Id Then
            RibbonStatusBar1.Cursor = Cursors.Hand
        Else
            RibbonStatusBar1.Cursor = Cursors.Default

        End If

    End Sub

    Private Sub LogPortableLine(ByVal ClearLog As Boolean, ByVal Text As String, Optional ByVal indentLevel As Integer = 0)
        If Me.InvokeRequired Then
            Dim tmp = Sub(Clear As Boolean, Txt As String, lvl As Integer)
                          LogPortableLine(Clear, Txt, lvl)
                      End Sub
            Me.Invoke(tmp, ClearLog, Text, indentLevel)
        Else
            If ClearLog Then memMakePortableStatus.Text = ""
            If indentLevel > 0 Then
                For x As Integer = 0 To indentLevel
                    memMakePortableStatus.Text &= vbTab

                Next
            End If

            memMakePortableStatus.Text &= Text & vbCrLf
            logger.Info(New String(vbTab, indentLevel) & "" & Text)
            memMakePortableStatus.SelectionStart = memMakePortableStatus.Text.Length - 1
            memMakePortableStatus.ScrollToCaret()


        End If


    End Sub
    Private Sub bwMakePortable_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwMakePortable.DoWork
        MakePortableVersion(e.Argument)

    End Sub
    Private Sub MakePortableVersion(ByVal path As String)
        Dim dt As Date = Now
        Dim Success As Boolean = True
        LogPortableLine(True, String.Format("Start make portable version:  {0} {1}", dt.ToShortDateString, dt.ToShortTimeString))
        Dim FzE As New SharpZip.Zip.FastZipEvents
        Dim tmp As String = IO.Path.Combine(IO.Path.GetTempPath, IO.Path.GetRandomFileName)

        FzE.FileFailure = Sub(sender As Object, e As ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs)
                              LogPortableLine(False, String.Format("Error extracting file '{0}'.  {1}", e.Name, e.Exception.Message), 2)

                              ' XtraEditors.XtraMessageBox.Show("Error Extracting files." & vbCrLf & e.Exception.Message, "Make Portable Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                              e.ContinueRunning = False
                              Success = False
                          End Sub
        FzE.DirectoryFailure = Sub(sender As Object, e As ICSharpCode.SharpZipLib.Core.ScanFailureEventArgs)
                                   e.ContinueRunning = False
                                   LogPortableLine(False, String.Format("Error processing directory '{0}'.  {1}", e.Name, e.Exception.Message), 2)
                                   Success = False

                               End Sub
        FzE.ProcessDirectory = Sub(sender As Object, e As ICSharpCode.SharpZipLib.Core.DirectoryEventArgs)
                                   LogPortableLine(False, String.Format("Processing the '{0}' directory.", e.Name), 2)

                               End Sub
        FzE.ProcessFile = Sub(sender As Object, e As ICSharpCode.SharpZipLib.Core.ScanEventArgs)
                              LogPortableLine(False, String.Format("Extracting:{0} to {1}.", e.Name, tmp), 1)

                          End Sub
        FzE.Progress = Sub(sender As Object, e As ICSharpCode.SharpZipLib.Core.ProgressEventArgs)
                           LogPortableLine(False, String.Format("{0}:{1}% processed.", e.Name, e.PercentComplete), 2)
                       End Sub
        Dim fz As New SharpZip.Zip.FastZip(FzE)
        Dim st As New Stopwatch
        LogPortableLine(False, "Extracting portable files to " & tmp & ".")



        st.Start()
        Try
            IO.Directory.CreateDirectory(tmp)
            fz.ExtractZip(My.Application.Info.DirectoryPath & "\Portable.zip", tmp, SharpZip.Zip.FastZip.Overwrite.Always, Nothing, "", "", True)
            If Success Then

                LogPortableLine(False, String.Format("Saving employee data to {0}.", IO.Path.Combine(tmp, My.Resources.EmployeeData)))
                employees.Save(IO.Path.Combine(path, My.Resources.EmployeeData))
                LogPortableLine(False, "Saving Boss key file to " & tmp)
                employees.Boss.SavePrivateKey(tmp)
                LogPortableLine(False, "Saving settings to " & tmp)
                updateScaleSetting()
                My.Settings.SavePortable(tmp)
                LogPortableLine(False, "Copying files to " & path)

                For Each f As String In IO.Directory.GetFiles(tmp)
                    Try
                        LogPortableLine(False, String.Format("Copying:{0} to {1}.", IO.Path.GetFileName(f), IO.Path.Combine(path, IO.Path.GetFileName(f))), 1)

                        IO.File.Copy(f, IO.Path.Combine(path, IO.Path.GetFileName(f)), True)

                    Catch ex As Exception
                        LogPortableLine(False, ex.Message, 2)
                        Success = False
                    Finally



                    End Try

                Next
                Try
                    LogPortableLine(False, "Deleting temp folder.")

                    IO.Directory.Delete(tmp, True)
                Catch ex As Exception
                    LogPortableLine(False, ex.Message, 1)
                End Try
                st.Stop()
            End If

        Catch ex As Exception
            Success = False
            LogPortableLine(False, "Error making portable version:" & ex.Message)


        End Try

        If Success Then
            LogPortableLine(False, "Make portable process completed.  It took " & st.Elapsed.TotalSeconds.ToString & " seconds to finish.")
        Else
            LogPortableLine(False, "Make portable version process failed!!!")

        End If
    End Sub
    Private Sub bbtnMakePortable_ItemClick(ByVal sender As System.Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnMakePortable.ItemClick
        If fdPortable.ShowDialog = Windows.Forms.DialogResult.OK Then
            dpMakePortable.Visibility = XtraBars.Docking.DockVisibility.Visible
            memMakePortableStatus.Focus()
            bbtnMakePortable.Enabled = False

            bwMakePortable.RunWorkerAsync(fdPortable.SelectedPath)




        End If
    End Sub
    Private Sub ShowStatus(ByVal Text As String)
        If Me.InvokeRequired Then
            Me.Invoke(Sub()
                          ShowStatus(Text)
                      End Sub)
        Else

            BarGeneralStatus.Caption = Text
        End If


    End Sub


    Private Sub bwMakePortable_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwMakePortable.RunWorkerCompleted
        bbtnMakePortable.Enabled = True
        memMakePortableStatus.Focus()
        dpMakePortable.Visibility = XtraBars.Docking.DockVisibility.AutoHide

    End Sub


    Private Sub bbtnGenerateTimeSlotReport_ItemClick(sender As System.Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnGenerateTimeSlotReport.ItemClick
        bbtnGenerateTimeSlotReport.Enabled = False
        Dim scheduletypes As String()
        If beFilterScheduleTypes.EditValue <> "" Then
            scheduletypes = CType(beFilterScheduleTypes.EditValue, String).Split(reFilterScheduleTypes.SeparatorChar)
        Else
            scheduletypes = {}
        End If


        System.Threading.Tasks.Task.Factory.StartNew(
            Sub()
                Dim sta As Boolean = Threading.Thread.CurrentThread.TrySetApartmentState(Threading.ApartmentState.STA)
                logger.Info("Word Generation Sta=" & sta.ToString)
                Me.ShowStatus("Generating Employee Schedule Report")
                Dim empTypes As String() = CType(beFilterEmployeeType.EditValue, String).Split(reFilterEmployeeTypes.SeparatorChar)


                Dim empd As New WeeklyScheduleData(dtChartView.EditValue, (From et In empTypes Select et.Trim).ToArray, TimeSpan.FromHours((Me.employees.WorkHours.GetSmallestWorkingHour + Me.employees.WorkHours.GetSmallestWorkingMinute / 60)), TimeSpan.FromHours((Me.employees.WorkHours.GetLargestWorkingHour + Me.employees.WorkHours.GetLargestWorkingMinute / 60)), TimeSpan.FromMinutes(60), GetEmps, scheduletypes)
                Dim wd As Microsoft.Office.Interop.Word.Application
                Try

                    wd = New Microsoft.Office.Interop.Word.Application

                    wd.ScreenUpdating = False
                    wd.Visible = False
                    wd.Documents.Add(Visible:=False).Activate()

                    With wd.ActiveDocument
                        With .PageSetup
                            .TopMargin = wd.InchesToPoints(0.25)
                            .RightMargin = wd.InchesToPoints(0.25)
                            .BottomMargin = wd.InchesToPoints(0.25)
                            .LeftMargin = wd.InchesToPoints(0.25)
                        End With

                        .CustomDocumentProperties.Add("Date Generated", False, Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeDate, Now)
                        .CustomDocumentProperties.add("Source", False, Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeString, "Employee Scheduler ©VBJay Solutions")
                        'Dim prop As Microsoft.Office.Core.DocumentProperty = From p As Microsoft.Office.Core.DocumentProperty In props Where p.Name = "Creation Date" Select p
                        'prop.Value = Now


                        wd.Selection.Paragraphs().Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter
                        wd.Selection.Range.Bold = True
                        wd.Selection.TypeText(String.Format("Generated on {0:d}", Now()))


                        With wd.Selection
                            '.Font.Bold = True
                            .EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory)

                        End With

                        wd.Selection.Range.Text = vbCrLf
                        wd.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory)
                        'wd.Selection.Range.Bold = False
                        With .Tables.Add(wd.Selection.Range, empd.SlotsPerDay + 1, empd.SlotDays + 1, Microsoft.Office.Interop.Word.WdDefaultTableBehavior.wdWord9TableBehavior, Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitContent)
                            For y As Integer = 1 To .Rows.Count
                                For x As Integer = 1 To .Columns.Count
                                    .Rows(y).Cells(x).VerticalAlignment = Microsoft.Office.Interop.Word.WdCellVerticalAlignment.wdCellAlignVerticalTop
                                    .Rows(y).Cells(x).HeightRule = Microsoft.Office.Interop.Word.WdRowHeightRule.wdRowHeightAuto
                                    .Rows(y).Cells(x).Range.Paragraphs.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter

                                Next
                            Next
                            .Rows(1).HeadingFormat = True


                            Dim days = From slt In empd.Slots Group By slt.Day Into SlotDays = Group Select Day

                            .Rows(1).Cells(1).Range.Text = "Time"
                            For hc As Integer = 2 To .Columns.Count
                                .Rows(1).Cells(hc).Range.Text = days(hc - 2).ToString

                            Next
                            For y As Integer = 2 To .Rows.Count
                                .Rows(y).Cells(1).Range.Text = String.Format("{0}-{1}", New Date(empd.Slots(y - 2).StartTime.Ticks).ToShortTimeString, New Date(empd.Slots(y - 2).EndTime.Ticks).ToShortTimeString)

                                For x As Integer = 2 To .Columns.Count

                                    Dim Slot As WeeklyScheduleData.TimeSlot = empd.Slots((x - 2) * empd.SlotsPerDay + y - 2)
                                    Dim sbEmp As New System.Text.StringBuilder
                                    For Each sch In Slot.Schedules
                                        If sch.StartTime.TimeOfDay > Slot.StartTime Then
                                            sbEmp.AppendFormat("({0})", sch.StartTime.ToShortTimeString)
                                        End If

                                        sbEmp.Append(sch.Employee.Name)
                                        If sch.ScheduleType <> "" Then
                                            sbEmp.AppendFormat(" ({0})", sch.ScheduleType)
                                        End If

                                        If sch.EndTime.TimeOfDay < Slot.EndTime Then
                                            sbEmp.AppendFormat("({0})", sch.EndTime.ToShortTimeString)

                                        End If
                                        If Slot.Schedules.Count - 1 <> Slot.Schedules.IndexOf(sch) Then sbEmp.AppendLine()
                                    Next


                                    With .Rows(y).Cells(x).Range
                                        .Text = sbEmp.ToString
                                        'apply any formatting to table row
                                    End With

                                    If Slot.Schedules.Count = 0 Then
                                        With .Rows(y).Cells(x).Shading
                                            .Texture = Microsoft.Office.Interop.Word.WdTextureIndex.wdTextureNone
                                            .ForegroundPatternColor = Microsoft.Office.Interop.Word.WdColor.wdColorAutomatic
                                            .BackgroundPatternColor = Microsoft.Office.Interop.Word.WdColor.wdColorBlack
                                        End With
                                    End If


                                Next
                            Next

                        End With

                    End With

                    wd.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory)

                    If wd.Selection.Information(Microsoft.Office.Interop.Word.WdInformation.wdActiveEndPageNumber) > 1 Then
                        wd.ActiveDocument.FitToPages()
                    End If
                    wd.Selection.InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdSectionBreakNextPage)
                    Dim tmpStr As New IO.MemoryStream()
                    chrtHours.Invoke(Sub()
                                         SetupChart(True)
                                         UpdateChart()
                                         chrtHours.Dock = DockStyle.None
                                         chrtHours.Size = New Size(wd.PointsToPixels(wd.InchesToPoints(16.44)), wd.PointsToPixels(wd.InchesToPoints(6.49)))
                                         chrtHours.SaveImage(tmpStr, Drawing.Imaging.ImageFormat.Png)
                                         chrtHours.Dock = DockStyle.Fill
                                         RefreshData()
                                     End Sub)

                    tmpStr.Seek(0, IO.SeekOrigin.Begin)
                    Dim jpg As Image = Image.FromStream(tmpStr, True, True)


                    My.Computer.Clipboard.SetImage(jpg)
                    wd.Selection.Paste()
                    wd.Selection.MoveUp(Microsoft.Office.Interop.Word.WdUnits.wdParagraph, Extend:=True)
                    With wd.Selection.InlineShapes(1)

                        .ScaleHeight = 55
                        .ScaleWidth = 55
                        With .ConvertToShape
                            .ThreeD.SetPresetCamera(Microsoft.Office.Core.MsoPresetCamera.msoCameraPerspectiveRelaxed)
                            .ConvertToInlineShape()

                        End With
                    End With

                    wd.Selection.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphLeft
                    wd.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory)

                    wd.Selection.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphLeft

                    With wd.Selection.FormattedText
                        .InsertParagraph()

                        wd.Selection.EndKey(Microsoft.Office.Interop.Word.WdUnits.wdStory)
                        wd.Selection.Font.Hidden = True
                        wd.Selection.TypeText("Chart will not update if table is modified.  You must regenerate the report with the modified times entered in the program.")
                    End With

                    With wd.Selection.Sections(1).PageSetup
                        .Orientation = Microsoft.Office.Interop.Word.WdOrientation.wdOrientLandscape
                        .VerticalAlignment = Microsoft.Office.Interop.Word.WdVerticalAlignment.wdAlignVerticalCenter
                    End With


                    'With wd.Selection.Sections(0).PageSetup
                    '    .LeftMargin = wd.InchesToPoints(0)
                    '    .RightMargin = wd.InchesToPoints(0)

                    'End With

                    wd.ActiveDocument.Saved = False
                    wd.Visible = True
                    wd.ScreenUpdating = True
                    wd.ScreenRefresh()
                    wd.Activate()

                    wd = Nothing
                    ShowStatus("Report generated.")
                    Me.Invoke(Sub()
                                  bbtnGenerateTimeSlotReport.Enabled = True
                              End Sub
)
                Catch ex As Exception
                    logger.ErrorException("Error generating word report", ex)

                    If wd IsNot Nothing Then
                        wd.Quit(Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges)
                    End If

                End Try
            End Sub, System.Threading.CancellationToken.None, TaskCreationOptions.None, My.Application.STAScheduler)

    End Sub

    Private Sub UpdateTimeSlotEnabled()
        If HaveSetupChart Then
            Dim emps As EmployeeList = GetEmps()
            bbtnGenerateTimeSlotReport.Enabled = emps.Count > 0 AndAlso (From e In emps From d In e.Days Select d).Sum(Function(d)
                                                                                                                           Return d.StartTimes.Count
                                                                                                                       End Function) > 0
        End If
    End Sub
    Private Sub filter_EditValueChanged(sender As Object, e As System.EventArgs) Handles beFilterScheduleTypes.EditValueChanged, beFilterEmployeeType.EditValueChanged, beFilterLocations.EditValueChanged
        If HaveSetupChart Then
            UpdateTimeSlotEnabled()
            RefreshData()
        End If
    End Sub





    Private Sub filter_CustomDisplayText(sender As Object, e As DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs) Handles reFilterScheduleTypes.CustomDisplayText, reFilterLocations.CustomDisplayText, reFilterEmployeeTypes.CustomDisplayText
        Dim ci As String = e.Value & ""
        Dim edit As XtraEditors.Repository.RepositoryItemCheckedComboBoxEdit
        If TypeOf sender Is XtraEditors.CheckedComboBoxEdit Then
            edit = CType(sender, XtraEditors.CheckedComboBoxEdit).Properties
        Else
            edit = sender
        End If

        If edit.GetItems.Count = ci.Split(edit.SeparatorChar).Count OrElse e.Value = "" Then
            e.DisplayText = "(All)"
        End If
    End Sub

    Private Sub dpSettings_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles dpSettings.Paint
        If ScheduleColors.BackColor <> dpSettings.BackColor Then ScheduleColors.BackColor = dpSettings.BackColor
    End Sub

    Private Sub ScheduleColors_ColorChanged(sender As Object, e As ScheduleTypeColorView.ColorChangedEventArgs) Handles ScheduleColors.ColorChanged
        Dim st As DevExpress.XtraScheduler.AppointmentStatus = (From s As DevExpress.XtraScheduler.AppointmentStatus In SchedulerStorage1.Appointments.Statuses Where s.DisplayName = e.ScheduleType).FirstOrDefault


        If st IsNot Nothing Then st.Color = e.newColor
        SchedulerStorage1.RefreshData()
    End Sub



    Private Sub bbtnInfo_ItemClick(sender As System.Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles bbtnInfo.ItemClick
        Dim about As New AboutBox
        about.ShowDialog()

    End Sub

    Private Sub ActiveViewRibbonPageGroup1_CaptionButtonClick(sender As System.Object, e As DevExpress.XtraBars.Ribbon.RibbonPageGroupEventArgs) Handles ActiveViewRibbonPageGroup1.CaptionButtonClick
        SchedulerControl1.ShowGotoDateForm()
    End Sub

    Private Sub SchedulerStorage1_AppointmentsDeleted(sender As Object, e As DevExpress.XtraScheduler.PersistentObjectsEventArgs) Handles SchedulerStorage1.AppointmentsDeleted

        If RestoringAppointment = False AndAlso DeletedHoliday = True Then
            DeletedHoliday = False
            tmrRebuild.Enabled = True
        End If

    End Sub
End Class